diff --git a/.depend b/.depend index 1d7d0606c65..152905fb7b7 100644 --- a/.depend +++ b/.depend @@ -26,8 +26,8 @@ auth2-kbdint.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd- auth2-methods.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h misc.h servconf.h openbsd-compat/sys-queue.h xmalloc.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth2-none.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h misc.h servconf.h ssh2.h monitor_wrap.h auth2-passwd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h packet.h openbsd-compat/sys-queue.h dispatch.h ssherr.h log.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h monitor_wrap.h misc.h servconf.h -auth2-pubkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h ssh.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h kex.h mac.h crypto_api.h sshbuf.h log.h ssherr.h misc.h servconf.h compat.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h -auth2-pubkey.o: pathnames.h uidswap.h auth-options.h canohost.h monitor_wrap.h authfile.h match.h channels.h session.h sk-api.h +auth2-pubkey.o: audit.h loginrec.h pathnames.h uidswap.h auth-options.h canohost.h monitor_wrap.h authfile.h match.h channels.h session.h sk-api.h +auth2-pubkey.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h xmalloc.h ssh.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h kex.h mac.h crypto_api.h sshbuf.h log.h ssherr.h misc.h servconf.h compat.h sshkey.h hostfile.h auth.h auth-pam.h auth2-pubkeyfile.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssh.h log.h ssherr.h misc.h sshkey.h digest.h hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h authfile.h match.h auth2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h atomicio.h xmalloc.h ssh2.h packet.h openbsd-compat/sys-queue.h dispatch.h log.h ssherr.h sshbuf.h misc.h servconf.h sshkey.h hostfile.h auth.h auth-pam.h audit.h loginrec.h pathnames.h monitor_wrap.h digest.h kex.h auth2.o: mac.h crypto_api.h @@ -71,6 +71,7 @@ kexgen.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat kexgex.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h kexgexc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h kexgexs.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h +kexmlkem768x25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sshkey.h kex.h mac.h crypto_api.h sshbuf.h digest.h ssherr.h log.h kexsntrup761x25519.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ssherr.h krl.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h sshbuf.h ssherr.h sshkey.h authfile.h misc.h log.h digest.h bitmap.h utf8.h krl.h log.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h match.h @@ -80,7 +81,7 @@ mac.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h match.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h match.h misc.h misc.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h misc.h log.h ssherr.h ssh.h sshbuf.h moduli.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -monitor.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h dh.h packet.h dispatch.h auth-options.h sshpty.h channels.h session.h sshlogin.h canohost.h log.h ssherr.h misc.h servconf.h monitor.h monitor_wrap.h monitor_fdpass.h compat.h ssh2.h authfd.h match.h sk-api.h +monitor.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h dh.h packet.h dispatch.h auth-options.h sshpty.h channels.h session.h sshlogin.h canohost.h log.h ssherr.h misc.h servconf.h monitor.h monitor_wrap.h monitor_fdpass.h compat.h ssh2.h authfd.h match.h sk-api.h srclimit.h monitor.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h openbsd-compat/openssl-compat.h atomicio.h xmalloc.h ssh.h sshkey.h sshbuf.h hostfile.h auth.h auth-pam.h audit.h loginrec.h cipher.h cipher-chachapoly.h monitor_fdpass.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h log.h ssherr.h monitor_fdpass.h monitor_wrap.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h sshbuf.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h kex.h mac.h crypto_api.h hostfile.h auth.h auth-pam.h audit.h @@ -98,20 +99,18 @@ platform.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-comp poly1305.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h poly1305.h progressmeter.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h progressmeter.h atomicio.h misc.h utf8.h readconf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h xmalloc.h ssh.h ssherr.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h pathnames.h log.h sshkey.h misc.h readconf.h match.h kex.h mac.h crypto_api.h uidswap.h -readconf.o: myproposal.h digest.h +readconf.o: myproposal.h digest.h version.h readpass.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h misc.h pathnames.h log.h ssherr.h ssh.h uidswap.h rijndael.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h rijndael.h sandbox-capsicum.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sandbox-darwin.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sandbox-null.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -sandbox-pledge.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sandbox-rlimit.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sandbox-seccomp-filter.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h sandbox-solaris.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h -sandbox-systrace.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h scp.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h xmalloc.h ssh.h atomicio.h pathnames.h log.h ssherr.h misc.h progressmeter.h utf8.h sftp.h sftp-common.h sftp-client.h servconf.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/glob.h openbsd-compat/sys-queue.h xmalloc.h ssh.h log.h ssherr.h sshbuf.h misc.h servconf.h pathnames.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h -servconf.o: mac.h crypto_api.h match.h channels.h groupaccess.h canohost.h packet.h dispatch.h hostfile.h auth.h auth-pam.h audit.h loginrec.h myproposal.h digest.h +servconf.o: mac.h crypto_api.h match.h channels.h groupaccess.h canohost.h packet.h dispatch.h hostfile.h auth.h auth-pam.h audit.h loginrec.h myproposal.h digest.h version.h serverloop.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h packet.h dispatch.h sshbuf.h log.h ssherr.h misc.h servconf.h canohost.h sshpty.h channels.h ssh2.h sshkey.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h serverloop.o: rijndael.h kex.h mac.h crypto_api.h hostfile.h auth.h auth-pam.h audit.h loginrec.h session.h auth-options.h serverloop.h session.o: hostfile.h auth.h auth-pam.h audit.h loginrec.h auth-options.h authfd.h pathnames.h log.h misc.h servconf.h sshlogin.h serverloop.h canohost.h session.h kex.h mac.h crypto_api.h monitor_wrap.h sftp.h atomicio.h @@ -160,9 +159,11 @@ sshconnect.o: authfd.h kex.h mac.h crypto_api.h sshconnect.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h xmalloc.h hostfile.h ssh.h sshbuf.h packet.h openbsd-compat/sys-queue.h dispatch.h sshkey.h sshconnect.h log.h ssherr.h match.h misc.h readconf.h atomicio.h dns.h monitor_fdpass.h ssh2.h version.h authfile.h sshconnect2.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshbuf.h packet.h dispatch.h compat.h cipher.h cipher-chachapoly.h chacha.h poly1305.h cipher-aesctr.h rijndael.h sshkey.h kex.h mac.h crypto_api.h sshconnect2.o: sshconnect.h authfile.h dh.h authfd.h log.h ssherr.h misc.h readconf.h match.h canohost.h msg.h pathnames.h uidswap.h hostfile.h utf8.h ssh-sk.h sk-api.h -sshd-session.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h kex.h mac.h crypto_api.h authfile.h pathnames.h atomicio.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h authfd.h msg.h channels.h session.h monitor.h monitor_wrap.h ssh-sandbox.h auth-options.h version.h sk-api.h srclimit.h dh.h +sshd-auth.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h kex.h mac.h crypto_api.h authfile.h pathnames.h atomicio.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h authfd.h msg.h channels.h session.h monitor.h monitor_wrap.h auth-options.h version.h sk-api.h srclimit.h ssh-sandbox.h dh.h +sshd-auth.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h log.h ssherr.h sshbuf.h misc.h match.h servconf.h uidswap.h compat.h cipher.h cipher-chachapoly.h +sshd-session.o: chacha.h poly1305.h cipher-aesctr.h rijndael.h digest.h sshkey.h kex.h mac.h crypto_api.h authfile.h pathnames.h atomicio.h canohost.h hostfile.h auth.h auth-pam.h audit.h loginrec.h authfd.h msg.h channels.h session.h monitor.h monitor_wrap.h auth-options.h version.h sk-api.h srclimit.h dh.h sshd-session.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h xmalloc.h ssh.h ssh2.h sshpty.h packet.h dispatch.h log.h ssherr.h sshbuf.h misc.h match.h servconf.h uidswap.h compat.h cipher.h cipher-chachapoly.h -sshd.o: audit.h loginrec.h authfd.h msg.h version.h sk-api.h addr.h srclimit.h +sshd.o: audit.h loginrec.h authfd.h msg.h version.h sk-api.h addr.h srclimit.h atomicio.h sshd.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h ./openbsd-compat/sys-tree.h openbsd-compat/sys-queue.h xmalloc.h ssh.h sshpty.h log.h ssherr.h sshbuf.h misc.h servconf.h compat.h digest.h sshkey.h authfile.h pathnames.h canohost.h hostfile.h auth.h auth-pam.h ssherr.o: ssherr.h sshkey-xmss.o: includes.h config.h defines.h platform.h openbsd-compat/openbsd-compat.h openbsd-compat/base64.h openbsd-compat/sigact.h openbsd-compat/readpassphrase.h openbsd-compat/vis.h openbsd-compat/getrrsetbyname.h openbsd-compat/sha1.h openbsd-compat/sha2.h openbsd-compat/md5.h openbsd-compat/blf.h openbsd-compat/fnmatch.h openbsd-compat/getopt.h openbsd-compat/bsd-signal.h openbsd-compat/bsd-misc.h openbsd-compat/bsd-setres_id.h openbsd-compat/bsd-statvfs.h openbsd-compat/bsd-waitpid.h openbsd-compat/bsd-poll.h openbsd-compat/fake-rfc2553.h openbsd-compat/bsd-cygwin_util.h openbsd-compat/port-aix.h openbsd-compat/port-irix.h openbsd-compat/port-linux.h openbsd-compat/port-solaris.h openbsd-compat/port-net.h openbsd-compat/port-uw.h openbsd-compat/bsd-nextstep.h entropy.h diff --git a/.git_allowed_signers b/.git_allowed_signers index 2a5fdc67c6e..04fe425ab89 100644 --- a/.git_allowed_signers +++ b/.git_allowed_signers @@ -1,7 +1,11 @@ -dtucker@dtucker.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKecyjh9aNmD4rb8WblA8v91JjRb0Cd2JtkzqxcggGeG +dtucker@dtucker.net valid-before="20241206" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKecyjh9aNmD4rb8WblA8v91JjRb0Cd2JtkzqxcggGeG dtucker@dtucker.net sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBDV81zWQ1+XVfWH5z4L4klDQ/z/6l2GLphfSTX/Rmq6kL5H8mkfzUlryxLlkN8cD9srtVJBAmwJWfJBNsCo958YAAAAEc3NoOg== +dtucker@dtucker.net sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIElSYahCw60CGct39Eg9EY8OLV9Ppr7tsudvSiMyNHOhAAAABHNzaDo= djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBLnJo3ZVDENYZGXm5uO9lU7b0iDFq5gHpTu1MaHPWTEfPdvw+AjFQQ/q5YizuMJkXGsMdYmblJEJZYHpm9IS7ZkAAAAEc3NoOg== djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBJoAXBTQalfg+kC5wy1vE7HkIHtVnmV6AUuuIo9KQ1P+70juHwvsFKpsGaqQbrHJkTVgYDGVP02XHj8+Fb18yBIAAAAEc3NoOg== djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBH+z1I48s6ydOhP5SJmI02zVCLf0K15B+UMHgoTIKVfUIv5oDoVX7e9f+7QiRmTeEOdZfQydiaVqsfi7qPSve+0AAAAEc3NoOg== djm@mindrot.org sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBPM4BmUg/fMnsl42JwktTekk/mB8Be3M+yK2ayg6lqYsqEri8yhRx84gey51OHKVk1TwlGbJjcMHI4URreDBEMQAAAAEc3NoOg== + +tim@multitalents.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC/L8E1DfiZ9cHzygqx0IzRCSAlmh4tXH7mZPwWZEY1L + diff --git a/.github/ci-status.md b/.github/ci-status.md index 4fa73894ce7..68275715dfb 100644 --- a/.github/ci-status.md +++ b/.github/ci-status.md @@ -6,6 +6,10 @@ master : [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/openssh.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:openssh) [![Coverity Status](https://scan.coverity.com/projects/21341/badge.svg)](https://scan.coverity.com/projects/openssh-portable) +9.9 : +[![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg?branch=V_9_9)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml?query=branch:V_9_9) +[![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg?branch=V_9_9)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_9_9) + 9.8 : [![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg?branch=V_9_8)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml?query=branch:V_9_8) [![C/C++ CI self-hosted](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml/badge.svg?branch=V_9_8)](https://github.com/openssh/openssh-portable-selfhosted/actions/workflows/selfhosted.yml?query=branch:V_9_8) diff --git a/.github/configs b/.github/configs index 6134cb6ed5e..2526e3ef481 100755 --- a/.github/configs +++ b/.github/configs @@ -129,6 +129,7 @@ case "$config" in kitchensink) CONFIGFLAGS="--with-kerberos5 --with-libedit --with-pam" CONFIGFLAGS="${CONFIGFLAGS} --with-security-key-builtin --with-selinux" + CONFIGFLAGS="${CONFIGFLAGS} --with-linux-memlock-onfault" CFLAGS="-DSK_DEBUG -DSANDBOX_SECCOMP_FILTER_DEBUG" ;; hardenedmalloc) @@ -136,6 +137,13 @@ case "$config" in ;; tcmalloc) CONFIGFLAGS="--with-ldflags=-ltcmalloc" + # tcmalloc may, depending on the stacktrace generator it uses, create + # pipe(2) fds during shared library initialisation. These will later + # get clobbered by ssh/sshd calling closefrom() and chaos will ensue. + # Tell tcmalloc to use an unwinder that doesn't pull this stuff. + TCMALLOC_STACKTRACE_METHOD=generic_fp + TEST_SSH_SSHD_ENV="TCMALLOC_STACKTRACE_METHOD=generic_fp" + export TCMALLOC_STACKTRACE_METHOD TEST_SSH_SSHD_ENV ;; krb5|heimdal) CONFIGFLAGS="--with-kerberos5" @@ -161,6 +169,9 @@ case "$config" in CONFIGFLAGS="--disable-pkcs11" LIBCRYPTOFLAGS="--with-ssl-dir=/opt/boringssl --with-rpath=-Wl,-rpath," ;; + aws-lc) + LIBCRYPTOFLAGS="--with-ssl-dir=/opt/aws-lc --with-rpath=-Wl,-rpath," + ;; libressl-*) LIBCRYPTOFLAGS="--with-ssl-dir=/opt/libressl --with-rpath=-Wl,-rpath," ;; @@ -181,13 +192,13 @@ case "$config" in CONFIGFLAGS="--with-selinux" ;; sk) - CONFIGFLAGS="--with-security-key-builtin" + CONFIGFLAGS="--with-security-key-builtin --with-security-key-standalone" ;; without-openssl) LIBCRYPTOFLAGS="--without-openssl" TEST_TARGET=t-exec ;; - valgrind-[1-5]|valgrind-unit) + valgrind-[1-4]|valgrind-unit) # rlimit sandbox and FORTIFY_SOURCE confuse Valgrind. CONFIGFLAGS="--without-sandbox --without-hardening" CONFIGFLAGS="$CONFIGFLAGS --with-cppflags=-D_FORTIFY_SOURCE=0" @@ -197,10 +208,9 @@ case "$config" in # Valgrind slows things down enough that the agent timeout test # won't reliably pass, and the unit tests run longer than allowed # by github so split into separate tests. - tests2="integrity try-ciphers" + tests2="integrity try-ciphers rekey" tests3="krl forward-control sshsig agent-restrict kextype sftp" tests4="cert-userkey cert-hostkey kextype sftp-perm keygen-comment percent" - tests5="rekey" case "$config" in valgrind-1) # All tests except agent-timeout (which is flaky under valgrind), @@ -220,9 +230,6 @@ case "$config" in valgrind-4) LTESTS="${tests4}" ;; - valgrind-5) - LTESTS="${tests5}" - ;; valgrind-unit) TEST_TARGET="unit USE_VALGRIND=1" ;; @@ -270,6 +277,10 @@ case "${TARGET_HOST}" in # Native linker is not great with PIC so OpenSSL is built w/out. CONFIGFLAGS="${CONFIGFLAGS} --disable-security-key" ;; + fbsd14-ppc64) + # Disable security key tests for bigendian interop test. + CONFIGFLAGS="${CONFIGFLAGS} --disable-security-key" + ;; hurd) SKIP_LTESTS="forwarding multiplex proxy-connect hostkey-agent agent-ptrace" ;; @@ -300,8 +311,20 @@ case "${TARGET_HOST}" in # SHA256 functions in sha2.h conflict with OpenSSL's breaking sk-dummy CONFIGFLAGS="${CONFIGFLAGS} --without-hardening --disable-security-key" ;; + openwrt-mipsel) + # Test most of the flags that OpenWRT sets for their package build. + # We only do this on one OpenWRT target for better coverage. + # The installed shared libraries installed by default are stripped and + # can't be linked to on the target systems. + OPENWRT_FLAGS="--disable-strip --disable-lastlog + --disable-utmp --disable-utmpx --disable-wtmp --disable-wtmpx + --with-stackprotect --with-cflags-after=-fzero-call-used-regs=skip" + CONFIGFLAGS="${CONFIGFLAGS} $(echo ${OPENWRT_FLAGS}) --without-zlib --disable-security-key" + LIBCRYPTOFLAGS="--without-openssl" + TEST_TARGET="t-exec" + ;; openwrt-*) - CONFIGFLAGS="${CONFIGFLAGS} --without-zlib" + CONFIGFLAGS="${CONFIGFLAGS} --without-zlib --disable-security-key" LIBCRYPTOFLAGS="--without-openssl" TEST_TARGET="t-exec" ;; diff --git a/.github/run_test.sh b/.github/run_test.sh index 17c1731ff86..74ab2423c0d 100755 --- a/.github/run_test.sh +++ b/.github/run_test.sh @@ -33,17 +33,31 @@ output_failed_logs() { } trap output_failed_logs 0 +env="" +if [ ! -z "${SUDO}" ]; then + env="${env} SUDO=${SUDO}" +fi +if [ ! -z "${TCMALLOC_STACKTRACE_METHOD}" ]; then + env="${env} TCMALLOC_STACKTRACE_METHOD=${TCMALLOC_STACKTRACE_METHOD}" +fi +if [ ! -z "${TEST_SSH_SSHD_ENV}" ]; then + env="${env} TEST_SSH_SSHD_ENV=${TEST_SSH_SSHD_ENV}" +fi +if [ ! -z "${env}" ]; then + env="env${env}" +fi + if [ -z "${LTESTS}" ]; then - make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}" + ${env} make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}" else - make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}" + ${env} make ${TEST_TARGET} SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}" fi if [ ! -z "${SSHD_CONFOPTS}" ]; then echo "rerunning t-exec with TEST_SSH_SSHD_CONFOPTS='${SSHD_CONFOPTS}'" if [ -z "${LTESTS}" ]; then - make t-exec SKIP_LTESTS="${SKIP_LTESTS}" TEST_SSH_SSHD_CONFOPTS="${SSHD_CONFOPTS}" + ${env} make t-exec SKIP_LTESTS="${SKIP_LTESTS}" TEST_SSH_SSHD_CONFOPTS="${SSHD_CONFOPTS}" else - make t-exec SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}" TEST_SSH_SSHD_CONFOPTS="${SSHD_CONFOPTS}" + ${env} make t-exec SKIP_LTESTS="${SKIP_LTESTS}" LTESTS="${LTESTS}" TEST_SSH_SSHD_CONFOPTS="${SSHD_CONFOPTS}" fi fi diff --git a/.github/setup_ci.sh b/.github/setup_ci.sh index f0f2761c710..f6c4a5c84fb 100755 --- a/.github/setup_ci.sh +++ b/.github/setup_ci.sh @@ -14,7 +14,7 @@ case "$host" in echo Removing extended ACLs so umask works as expected. setfacl -b . regress PACKAGES="$PACKAGES,autoconf,automake,cygwin-devel,gcc-core" - PACKAGES="$PACKAGES,make,openssl-devel,zlib-devel" + PACKAGES="$PACKAGES,make,openssl,libssl-devel,zlib-devel" ;; *-darwin*) PACKAGER=brew @@ -142,6 +142,10 @@ for TARGET in $TARGETS; do INSTALL_BORINGSSL=1 PACKAGES="${PACKAGES} cmake ninja-build" ;; + aws-lc) + INSTALL_AWSLC=1 + PACKAGES="${PACKAGES} cmake ninja-build" + ;; putty-*) INSTALL_PUTTY=$(echo "${TARGET}" | cut -f2 -d-) PACKAGES="${PACKAGES} cmake" @@ -240,6 +244,15 @@ if [ ! -z "${INSTALL_BORINGSSL}" ]; then cp -r ${HOME}/boringssl/include /opt/boringssl) fi +if [ ! -z "${INSTALL_AWSLC}" ]; then + (cd ${HOME} && git clone --depth 1 --branch v1.46.1 https://github.com/aws/aws-lc.git && + cd ${HOME}/aws-lc && mkdir build && cd build && + cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF .. && ninja && + mkdir -p /opt/aws-lc/lib && + cp ${HOME}/aws-lc/build/crypto/libcrypto.a /opt/aws-lc/lib && + cp -r ${HOME}/aws-lc/include /opt/aws-lc) +fi + if [ ! -z "${INSTALL_ZLIB}" ]; then (cd ${HOME} && git clone https://github.com/madler/zlib.git && cd ${HOME}/zlib && ./configure && make && diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index ec6b67e70e7..a88a4cc3633 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -3,9 +3,9 @@ name: C/C++ CI on: workflow_dispatch: # disable for win32-openssh fork # push: - # paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/workflows/c-cpp.yaml' ] + # paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/workflows/c-cpp.yml' ] # pull_request: - # paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/workflows/c-cpp.yaml' ] + # paths: [ '**.c', '**.h', '**.m4', '**.sh', '**/Makefile.in', 'configure.ac', '.github/configs', '.github/workflows/c-cpp.yml' ] jobs: ci: @@ -16,11 +16,13 @@ jobs: matrix: # First we test all OSes in the default configuration. target: - - ubuntu-20.04 - ubuntu-22.04 - - macos-12 + - ubuntu-latest + - ubuntu-22.04-arm + - ubuntu-24.04-arm - macos-13 - macos-14 + - macos-15 - windows-2019 - windows-2022 config: [default] @@ -29,34 +31,36 @@ jobs: include: - { target: windows-2019, config: cygwin-release } - { target: windows-2022, config: cygwin-release } - - { target: ubuntu-20.04, config: valgrind-1 } - - { target: ubuntu-20.04, config: valgrind-2 } - - { target: ubuntu-20.04, config: valgrind-3 } - - { target: ubuntu-20.04, config: valgrind-4 } - - { target: ubuntu-20.04, config: valgrind-5 } - - { target: ubuntu-20.04, config: valgrind-unit } - - { target: ubuntu-20.04, config: c89 } - - { target: ubuntu-20.04, config: clang-6.0 } - - { target: ubuntu-20.04, config: clang-8 } - - { target: ubuntu-20.04, config: clang-9 } - - { target: ubuntu-20.04, config: clang-10 } - - { target: ubuntu-20.04, config: clang-11 } - - { target: ubuntu-20.04, config: clang-12-Werror } - - { target: ubuntu-20.04, config: clang-sanitize-address } - - { target: ubuntu-20.04, config: clang-sanitize-undefined } - - { target: ubuntu-20.04, config: gcc-sanitize-address } - - { target: ubuntu-20.04, config: gcc-sanitize-undefined } - - { target: ubuntu-20.04, config: gcc-7 } - - { target: ubuntu-20.04, config: gcc-8 } - - { target: ubuntu-20.04, config: gcc-10 } + - { target: ubuntu-22.04, config: c89 } + - { target: ubuntu-22.04, config: clang-11 } + - { target: ubuntu-22.04, config: clang-12-Werror } + - { target: ubuntu-22.04, config: clang-14 } + - { target: ubuntu-22.04, config: clang-sanitize-address } + - { target: ubuntu-22.04, config: clang-sanitize-undefined } + - { target: ubuntu-22.04, config: gcc-9 } - { target: ubuntu-22.04, config: gcc-11-Werror } - { target: ubuntu-22.04, config: gcc-12-Werror } - - { target: ubuntu-20.04, config: pam } - - { target: ubuntu-20.04, config: kitchensink } + - { target: ubuntu-22.04, config: gcc-sanitize-address } + - { target: ubuntu-22.04, config: gcc-sanitize-undefined } - { target: ubuntu-22.04, config: hardenedmalloc } - - { target: ubuntu-20.04, config: tcmalloc } - - { target: ubuntu-20.04, config: musl } + - { target: ubuntu-22.04, config: heimdal } + - { target: ubuntu-22.04, config: kitchensink } + - { target: ubuntu-22.04, config: krb5 } + - { target: ubuntu-22.04, config: libedit } + - { target: ubuntu-22.04, config: pam } + - { target: ubuntu-22.04, config: selinux } + - { target: ubuntu-22.04, config: sk } + - { target: ubuntu-22.04, config: valgrind-1 } + - { target: ubuntu-22.04, config: valgrind-2 } + - { target: ubuntu-22.04, config: valgrind-3 } + - { target: ubuntu-22.04, config: valgrind-4 } + - { target: ubuntu-22.04, config: valgrind-unit } + - { target: ubuntu-22.04, config: without-openssl } + - { target: ubuntu-latest, config: gcc-14 } + - { target: ubuntu-latest, config: clang-15 } + - { target: ubuntu-latest, config: clang-19 } - { target: ubuntu-latest, config: boringssl } + - { target: ubuntu-latest, config: aws-lc } - { target: ubuntu-latest, config: libressl-master } - { target: ubuntu-latest, config: libressl-3.2.6 } - { target: ubuntu-latest, config: libressl-3.3.6 } @@ -65,18 +69,20 @@ jobs: - { target: ubuntu-latest, config: libressl-3.6.1 } - { target: ubuntu-latest, config: libressl-3.7.2 } - { target: ubuntu-latest, config: libressl-3.8.4 } - - { target: ubuntu-latest, config: libressl-3.9.1 } + - { target: ubuntu-latest, config: libressl-3.9.2 } + - { target: ubuntu-latest, config: libressl-4.0.0 } - { target: ubuntu-latest, config: openssl-master } - { target: ubuntu-latest, config: openssl-noec } - { target: ubuntu-latest, config: openssl-1.1.1 } - { target: ubuntu-latest, config: openssl-1.1.1t } - { target: ubuntu-latest, config: openssl-1.1.1w } - { target: ubuntu-latest, config: openssl-3.0.0 } - - { target: ubuntu-latest, config: openssl-3.0.13 } + - { target: ubuntu-latest, config: openssl-3.0.15 } - { target: ubuntu-latest, config: openssl-3.1.0 } - - { target: ubuntu-latest, config: openssl-3.1.5 } - - { target: ubuntu-latest, config: openssl-3.2.1 } - - { target: ubuntu-latest, config: openssl-3.3.0 } + - { target: ubuntu-latest, config: openssl-3.1.7 } + - { target: ubuntu-latest, config: openssl-3.2.3 } + - { target: ubuntu-latest, config: openssl-3.3.2 } + - { target: ubuntu-latest, config: openssl-3.4.0 } - { target: ubuntu-latest, config: openssl-1.1.1_stable } - { target: ubuntu-latest, config: openssl-3.0 } # stable branch - { target: ubuntu-latest, config: openssl-3.1 } # stable branch @@ -92,19 +98,18 @@ jobs: - { target: ubuntu-latest, config: putty-0.78 } - { target: ubuntu-latest, config: putty-0.79 } - { target: ubuntu-latest, config: putty-0.80 } + - { target: ubuntu-latest, config: putty-0.81 } + - { target: ubuntu-latest, config: putty-0.82 } + - { target: ubuntu-latest, config: putty-0.83 } - { target: ubuntu-latest, config: putty-snapshot } - { target: ubuntu-latest, config: zlib-develop } - - { target: ubuntu-22.04, config: pam } - - { target: ubuntu-22.04, config: krb5 } - - { target: ubuntu-22.04, config: heimdal } - - { target: ubuntu-22.04, config: libedit } - - { target: ubuntu-22.04, config: sk } - - { target: ubuntu-22.04, config: selinux } - - { target: ubuntu-22.04, config: kitchensink } - - { target: ubuntu-22.04, config: without-openssl } - - { target: macos-12, config: pam } + - { target: ubuntu-latest, config: tcmalloc } + - { target: ubuntu-latest, config: musl } + - { target: ubuntu-22.04-arm, config: kitchensink } + - { target: ubuntu-24.04-arm, config: kitchensink } - { target: macos-13, config: pam } - { target: macos-14, config: pam } + - { target: macos-15, config: pam } runs-on: ${{ matrix.target }} steps: - name: set cygwin git params diff --git a/.github/workflows/selfhosted.yml b/.github/workflows/selfhosted.yml index 37594a24e05..f2f27577a92 100644 --- a/.github/workflows/selfhosted.yml +++ b/.github/workflows/selfhosted.yml @@ -22,6 +22,7 @@ jobs: REMOTE: ${{ startsWith(matrix.host, 'remote') }} VM: ${{ startsWith(matrix.host, 'libvirt') || startsWith(matrix.host, 'persist') }} SSHFS: ${{ startsWith(matrix.host, 'libvirt') || startsWith(matrix.host, 'persist') || startsWith(matrix.host, 'remote') }} + BIGENDIAN: ${{ matrix.target == 'aix51' || matrix.target == 'fbsd14-ppc64' || matrix.target == 'openwrt-mips' }} strategy: fail-fast: false # We use a matrix in two parts: firstly all of the VMs are tested with the @@ -41,11 +42,11 @@ jobs: - fbsd12 - fbsd13 - fbsd14 - - minix3 - nbsd3 - nbsd4 - nbsd8 - nbsd9 + - nbsd10 - obsd51 - obsd67 - obsd72 @@ -53,6 +54,7 @@ jobs: - obsd74 - obsdsnap - obsdsnap-i386 + - omnios - openindiana - ubuntu-2204 config: @@ -62,6 +64,7 @@ jobs: include: # Long-running/slow tests have access to high priority runners. - { target: aix51, config: default, host: libvirt-hipri } + - { target: fbsd14-ppc64, config: default, host: libvirt-hipri } - { target: openindiana, config: pam, host: libvirt-hipri } - { target: sol10, config: default, host: libvirt-hipri } - { target: sol10, config: pam, host: libvirt-hipri } @@ -76,6 +79,7 @@ jobs: - { target: dfly58, config: pam, host: libvirt } - { target: dfly60, config: pam, host: libvirt } - { target: dfly62, config: pam, host: libvirt } + - { target: dfly64, config: pam, host: libvirt } - { target: fbsd10, config: pam, host: libvirt } - { target: fbsd12, config: pam, host: libvirt } - { target: fbsd13, config: pam, host: libvirt } @@ -83,6 +87,7 @@ jobs: - { target: nbsd8, config: pam, host: libvirt } - { target: nbsd9, config: pam, host: libvirt } - { target: nbsd10, config: pam, host: libvirt } + - { target: omnios, config: pam, host: libvirt } # ARM64 VMs - { target: obsd-arm64, config: default, host: libvirt-arm64 } # VMs with persistent disks that have their own runner. @@ -94,14 +99,9 @@ jobs: - { target: ARM64, config: pam, host: ARM64 } # Physical hosts with remote runners. - { target: debian-riscv64, config: default, host: remote-debian-riscv64 } - - { target: openwrt-mips, config: default, host: remote-openwrt-mips } - { target: openwrt-mipsel, config: default, host: remote-openwrt-mipsel } steps: - - name: unmount stale workspace - if: env.SSHFS == 'true' - run: fusermount -u ${GITHUB_WORKSPACE} || true - working-directory: ${{ runner.temp }} - name: shutdown VM if running if: env.VM == 'true' run: vmshutdown @@ -145,6 +145,60 @@ jobs: if: always() && env.SSHFS == 'true' run: fusermount -u ${GITHUB_WORKSPACE} || true working-directory: ${{ runner.temp }} + + - name: bigendian interop - mount regress + if: env.SSHFS == 'true' && env.BIGENDIAN == 'true' + run: | + set -x + vmrun sudo chown -R $LOGNAME ~/$(basename ${GITHUB_WORKSPACE}) || true + vmrun "cd $(basename ${GITHUB_WORKSPACE}/regress) && sudo make clean" + sshfs_mount regress + vmrun "sudo mkdir -p $(dirname ${GITHUB_WORKSPACE})" + vmrun "sudo ln -s ~/$(basename ${GITHUB_WORKSPACE}) ${GITHUB_WORKSPACE}" + working-directory: ${{ runner.temp }} + + - name: bigendian interop - host build + if: env.SSHFS == 'true' && env.BIGENDIAN == 'true' + run: | + set -x + ./.github/configure.sh ${{ matrix.config }} + pwd + ls -ld regress || true + ls -l regress/check-perm || true + make clean + make + + - name: bigendian interop - test + if: env.SSHFS == 'true' && env.BIGENDIAN == 'true' + env: + TEST_SSH_UNSAFE_PERMISSIONS: 1 + run: | + set -x + echo "#!/bin/sh" >remote_sshd + echo "exec /usr/bin/ssh ${TARGET_DOMAIN} exec /home/builder/$(basename ${GITHUB_WORKSPACE})/sshd "'$@' >>remote_sshd + chmod 755 remote_sshd + make t-exec TEST_SSH_SSHD=`pwd`/remote_sshd LTESTS="try-ciphers kextype keytype" + + - name: bigendian interop - save logs + if: failure() && env.BIGENDIAN == 'true' + uses: actions/upload-artifact@main + with: + name: ${{ matrix.target }}-${{ matrix.config }}-interop-logs + path: | + config.h + config.log + regress/*.log + regress/log/* + + - name: bigendian interop - unmount regress + if: always() && env.SSHFS == 'true' && env.BIGENDIAN == 'true' + run: fusermount -z -u ${GITHUB_WORKSPACE}/regress || true + working-directory: ${{ runner.temp }} + + - name: lazily unmount workspace + if: always() && env.SSHFS == 'true' + run: fusermount -z -u ${GITHUB_WORKSPACE} || true + working-directory: ${{ runner.temp }} - name: shutdown VM if: always() && env.VM == 'true' run: vmshutdown diff --git a/.github/workflows/upstream.yml b/.github/workflows/upstream.yml index 4c0e24acb4f..d08eae5d8eb 100644 --- a/.github/workflows/upstream.yml +++ b/.github/workflows/upstream.yml @@ -10,19 +10,25 @@ jobs: selfhosted: name: "upstream ${{ matrix.target }} ${{ matrix.config }}" if: github.repository == 'openssh/openssh-portable-selfhosted' - runs-on: 'libvirt' + runs-on: ${{ matrix.host }} env: DEBUG_ACTIONS: true EPHEMERAL: true - HOST: 'libvirt' + HOST: ${{ matrix.host }} TARGET_HOST: ${{ matrix.target }} TARGET_CONFIG: ${{ matrix.config }} TARGET_DOMAIN: ${{ format('{0}-{1}-{2}', matrix.target, matrix.config, github.run_id) || matrix.target }} strategy: fail-fast: false matrix: + host: + - libvirt target: [ obsdsnap, obsdsnap-i386 ] config: [ default, without-openssl, ubsan ] + include: + - { host: libvirt-arm64, target: obsdsnap-arm64, config: default } + - { host: libvirt-arm64, target: obsdsnap-arm64, config: without-openssl } + - { host: libvirt-arm64, target: obsdsnap-arm64, config: ubsan } steps: - name: unmount stale workspace run: fusermount -u ${GITHUB_WORKSPACE} || true @@ -50,17 +56,22 @@ jobs: env: SUDO: sudo timeout-minutes: 300 + - name: show logs + if: failure() + run: vmrun 'for i in /usr/src/regress/usr.bin/ssh/obj/*.log; do echo ====; echo logfile $i; echo =====; cat $i; done' - name: save logs if: failure() uses: actions/upload-artifact@main with: name: ${{ matrix.target }}-${{ matrix.config }}-logs path: | - /usr/obj/regress/usr.bin/ssh/obj/*.log - /usr/obj/regress/usr.bin/ssh/obj/log/* + /usr/src/regress/usr.bin/ssh/obj/*.log + /usr/src/regress/usr.bin/ssh/obj/log/* - name: unmount workspace if: always() - run: fusermount -u ${GITHUB_WORKSPACE} || true + run: | + fusermount -u ${GITHUB_WORKSPACE} || true + fusermount -z -u ${GITHUB_WORKSPACE} || true working-directory: ${{ runner.temp }} - name: shutdown VM if: always() diff --git a/.gitignore b/.gitignore index 1e922fefc8f..be2375f39a5 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,8 @@ survey.sh **/*.o **/*.lo **/*.so +**/*.dylib +**/*.dll **/*.out **/*.a **/*.un~ @@ -30,8 +32,10 @@ ssh-keysign ssh-pkcs11-helper ssh-sk-helper sshd -!regress/misc/fuzz-harness/Makefile -!regress/unittests/sshsig/Makefile +sshd-session +sshd-auth +!regress/misc/**/Makefile +!regress/unittests/**/Makefile tags # Ignores in Windows fork diff --git a/.skipped-commit-ids b/.skipped-commit-ids index ec7831e5ff5..7988e25006f 100644 --- a/.skipped-commit-ids +++ b/.skipped-commit-ids @@ -37,6 +37,8 @@ ef9341d5a50f0d33e3a6fbe995e92964bc7ef2d3 Makefile relinking changes fb39324748824cb0387e9d67c41d1bef945c54ea Makefile change 5f378c38ad8976d507786dc4db9283a879ec8cd0 Makefile change 112aacedd3b61cc5c34b1fa6d9fb759214179172 Makefile change +a959fc45ea3431b36f52eda04faefc58bcde00db groupaccess.c changes +6d07e4606997e36b860621a14dd41975f2902f8f Makefile.inc Old upstream tree: diff --git a/ChangeLog b/ChangeLog index a1a52651718..60a06386e42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8666 +1,7464 @@ -commit fa41f6592ff1b6ead4a652ac75af31eabb05b912 +commit 8725dbc5b5fcc3e326fc71189ef8dba4333362cc Author: Damien Miller -Date: Mon Jul 1 14:33:26 2024 +1000 +Date: Wed Apr 9 17:02:17 2025 +1000 - version numbers + update version numbers -commit bfebb8a5130a792c5356bd06e1ddef72a0a0449f +commit cc7feb9458ad3b893b53dc9c7500d1affd208bde Author: djm@openbsd.org -Date: Mon Jul 1 04:31:59 2024 +0000 +Date: Wed Apr 9 07:00:21 2025 +0000 - upstream: openssh-9.8 + upstream: openssh-10.0 - OpenBSD-Commit-ID: 5f8b89e38a4c5f7c6d52ffa19f796d49f36fab19 + OpenBSD-Commit-ID: db5b4a1f1c9e988f8f166b56dc5643606294b403 -commit 146c420d29d055cc75c8606327a1cf8439fe3a08 +commit fc86875e6acb36401dfc1dfb6b628a9d1460f367 Author: djm@openbsd.org -Date: Mon Jul 1 04:31:17 2024 +0000 +Date: Wed Apr 9 07:00:03 2025 +0000 - upstream: when sending ObscureKeystrokeTiming chaff packets, we + upstream: Fix logic error in DisableForwarding option. This option - can't rely on channel_did_enqueue to tell that there is data to send. This - flag indicates that the channels code enqueued a packet on _this_ ppoll() - iteration, not that data was enqueued in _any_ ppoll() iteration in the - timeslice. ok markus@ + was documented as disabling X11 and agent forwarding but it failed to do so. + Spotted by Tim Rice. - OpenBSD-Commit-ID: 009b74fd2769b36b5284a0188ade182f00564136 + OpenBSD-Commit-ID: fffc89195968f7eedd2fc57f0b1f1ef3193f5ed1 -commit 637e4dfea4ed81264e264b6200172ce319c64ead +commit dd73459e351b0a2908aed90910c8ff9b0b381c6d Author: djm@openbsd.org -Date: Mon Jul 1 03:10:19 2024 +0000 +Date: Wed Apr 9 01:24:40 2025 +0000 - upstream: use "lcd" to change directory before "lls" rather then "cd", - - since the directory we're trying to list is local. Spotted by Corinna - Vinschen + upstream: oops, I accidentally backed out the typo fix - OpenBSD-Regress-ID: 821feca4a4bebe491944e624c8f7f2990b891415 + OpenBSD-Commit-ID: f485f79bf3e9ebbe1de13ac96150cf458956cfd8 -commit c8cfe258cee0b8466ea84597bf15e1fcff3bc328 +commit 0cb945891944bada5850e85d60afa3c807cf1af6 Author: djm@openbsd.org -Date: Thu Jun 27 23:01:15 2024 +0000 +Date: Wed Apr 9 01:23:47 2025 +0000 - upstream: delete obsolete comment + upstream: typo - OpenBSD-Commit-ID: 5fb04f298ed155053f3fbfdf0c6fe7cdf84bbfa2 + OpenBSD-Commit-ID: f912725c7d303720706b3ccfb2cb846d46296d13 -commit 94b9d37100f6fa536aaa1d1a0e4926fe44fbf04d -Author: djm@openbsd.org -Date: Thu Jun 27 22:36:44 2024 +0000 +commit cd4a6bd50b658d707867caa1f5aa40b35c2b6c19 +Author: Damien Miller +Date: Wed Apr 9 09:49:55 2025 +1000 - upstream: retire unused API - - OpenBSD-Commit-ID: 3e30d7b0615e2707f6bbe70f61b1c2f72f78161b + initialise websafe_allowlist in agent fuzzer -commit 268c3a7f5783e731ed60f4e28da66ee3743581d3 -Author: jmc@openbsd.org -Date: Thu Jun 27 21:02:16 2024 +0000 +commit 55b7cb48af96c1102ef8ab5a73bb329cbed30945 +Author: djm@openbsd.org +Date: Tue Apr 8 23:10:46 2025 +0000 - upstream: ssl(8) no longer contains a HISTORY section; + upstream: typo - OpenBSD-Commit-ID: 83b7ff34433d79595e9c2a5d2a561a6660251245 + OpenBSD-Regress-ID: 08477b936d1d0c1e8a98aa1c0e1bdde8871894c9 -commit 12b6cc09ce6c430681f03af2a8069e37a664690b +commit 985d8cbcd3438cc36b4e709476f1783e358ddfb1 Author: djm@openbsd.org -Date: Wed Jun 26 23:47:46 2024 +0000 +Date: Tue Apr 8 23:10:08 2025 +0000 - upstream: move child process waitpid() loop out of SIGCHLD handler; - - ok deraadt + upstream: typo - OpenBSD-Commit-ID: 65815a39564e431414aed7c5ace8076f4e9ca741 + OpenBSD-Commit-ID: 6e683e13e72bf1e43bbd3bbc6a8332d5a98bdc99 -commit d6bcd13297c2ab8b528df5a6898f994734849031 -Author: deraadt@openbsd.org -Date: Wed Jun 26 23:16:52 2024 +0000 +commit 000c3d14e94d8f7597087c457260ea9417045b65 +Author: dtucker@openbsd.org +Date: Mon Apr 7 08:12:22 2025 +0000 - upstream: Instead of using possibly complex ssh_signal(), write all + upstream: Include time.h for time(). - the parts of the grace_alarm_handler() using the exact things allowed by the - signal-safe rules. This is a good rule of thumb: Handlers should be written - to either set a global volatile sig_atomic_t inspected from outside, and/or - directly perform only safe operations listed in our sigaction(2) manual page. - ok djm markus + Fixes warning on some platforms when building without openssl. - OpenBSD-Commit-ID: 14168ae8368aab76e4ed79e17a667cb46f404ecd + OpenBSD-Commit-ID: 04ca29b8eaae1860c7adde3e770baa1866e30a54 -commit b8793e2b0851f7d71b97554fa5260b23796d6277 -Author: deraadt@openbsd.org -Date: Wed Jun 26 23:14:14 2024 +0000 +commit 49b8b9bf829e08af22366530614a5e59ac341ca9 +Author: tb@openbsd.org +Date: Wed Apr 2 04:28:03 2025 +0000 - upstream: save_errno wrappers inside two small signal handlers that + upstream: Wrap #include in #ifdef WITH_DSA - perform system calls, for systems with libc that do perform libc sigtramps. - ok djm markus + ok djm - OpenBSD-Commit-ID: 7749b56419a7c9dcfe4c6c04811e429813346c62 + OpenBSD-Commit-ID: ed01a7c102243f84e4a317aefb431916d98aab15 -commit f23e9332c4c8df37465c4a4f38275ea98980ed7e -Author: jmc@openbsd.org -Date: Mon Jun 24 06:59:39 2024 +0000 +commit f80fb819e5521e13f167edbcc3eed66e22ad0c2a +Author: Damien Miller +Date: Thu Apr 3 09:10:19 2025 +1100 - upstream: - uppercase start of sentence - correct sentence grammar - - ok djm + remove all instances of -pie from LDFLAGS - OpenBSD-Commit-ID: 1ec4b0fdb633a43667f2c8fff1d600bd647dde25 + Previously only the first instance of this flag was removed. + Unbreaks build on OpenSUSE Tumbleweed. Patch from Antonio Larrosa -commit 1839e3eb71a759aa795602c1e4196300f4ac2615 +commit 6c9872faa1c297a84c6d3e3b95a927be99eadbf6 Author: djm@openbsd.org -Date: Mon Jun 24 04:05:11 2024 +0000 +Date: Tue Apr 1 23:23:20 2025 +0000 - upstream: mention SshdSessionPath option + upstream: remove ability to enable DSA support. Actual code will be - OpenBSD-Commit-ID: c29734d36c21003973b15c1c9965c35f36cef30c + g/c'd separately. ok deraadt@ + + OpenBSD-Commit-ID: 2a032b75156c4d922e8343fa97ff6bc227f09819 -commit 603193e32aef5db7d60c58066d5de89806e79312 -Author: Darren Tucker -Date: Thu Jun 20 18:45:14 2024 +1000 +commit 8460aaa4e1f8680f03cc5334556b9440b401f010 +Author: dtucker@openbsd.org +Date: Fri Mar 28 21:45:55 2025 +0000 - Rerun upstream tests on .sh file changes too. + upstream: Add TEST_SSH_SSHD_ENV to sshd lines here too. + + OpenBSD-Regress-ID: 045f2c88b42d694b404db51c5de5eca20d748ff1 -commit dbbf9337c19381786a8e5a8a49152fe6b80c780d +commit 5e60f5937b9c33190b9d7614f72d85d4a9b38d3d Author: dtucker@openbsd.org -Date: Thu Jun 20 08:23:18 2024 +0000 +Date: Fri Mar 28 06:04:07 2025 +0000 - upstream: Work around dbclient cipher/mac query bug. + upstream: Pass "ControlMaster no" to ssh when invoked by scp & sftp. - Unlike earlier versions, recent Dropbear (at least v2024.85) requires - a host arg when querying supported ciphers and macs via "-c/-m - help". Earlier versions accept but do not require it, so always - provide it. If these queries fail, skip the test with a warning. + If you have ControlMaster auto (or yes) in your config, and the + first connection you make is via scp or sftp, then you may get a + few unexpected options applied to it (eg ForwardX11 no), since sftp + and sftp explicitly disable those for reasons. These effects will + persist beyond the initial scp or sftp command. - OpenBSD-Regress-ID: 98eb863a3f0363416922efb273885e6b3c7f68d4 + This explicitly disables persistent session *creation* by scp and sftp. + It will not prevent them from using an existing session if one has + already been created. + + From Github PR#557, ok djm@ kn@ + + OpenBSD-Commit-ID: 9dad7c737466837e0150c4318920f46d844770c4 -commit 8de2c8cebc46bbdb94b7a2c120fcadfb66a3cccc +commit bbd36869dfb4b770cc9e6a345c04a585a0955aec Author: dtucker@openbsd.org -Date: Thu Jun 20 08:18:34 2024 +0000 +Date: Fri Mar 28 05:41:15 2025 +0000 - upstream: Remove dropbear key types not supported - - by current OpenSSH. Allows subsequent test runs to work if OpenSSH is - rebuilt w/out OpenSSL. + upstream: Set sshd environment variables during sshd test run too. - OpenBSD-Regress-ID: e0129eb2b1d31771105903a8055216fbba20a770 + OpenBSD-Regress-ID: 50cb325d92c390a2909662c901f6ac5d80b6f74d -commit e9b6471c59b21e5d9ef1b3832d4bf727338add85 -Author: djm@openbsd.org -Date: Thu Jun 20 00:18:05 2024 +0000 +commit 98f05b1484daddef2f56b79e24540523b5016143 +Author: dtucker@openbsd.org +Date: Fri Mar 28 05:36:24 2025 +0000 - upstream: stricter check for overfull tables in penalty record path + upstream: Add TEST_SSH_SSHD_ENV variable which is added to sshd's - OpenBSD-Commit-ID: 7df01e648a0723418c554e64a9f2b6d38db060a6 + environment. Will be used in Portable to tweak behaviour of tcmalloc's + debugging. + + OpenBSD-Regress-ID: 67e38c3c4517ddb72c8a3549a3325a166d7bb6d6 -commit d9336d344eb2a1e898c5e66147b3f108c7214694 -Author: djm@openbsd.org -Date: Wed Jun 19 23:24:47 2024 +0000 +commit 8cd9ed4df0eccc825eca0c45354a37332e125e38 +Author: dtucker@openbsd.org +Date: Fri Mar 28 05:33:30 2025 +0000 - upstream: put back reaping of preauth child process when writes + upstream: chown log directory in addition to log files. - from the monitor fail. Not sure how this got lost in the avalanche of - patches. + OpenBSD-Regress-ID: b520d54a0bbf2c6554413c798218bda26b385ad9 + +commit e32de6bf4f3229d4838beb127de45eed1377ccc5 +Author: Darren Tucker +Date: Fri Mar 28 16:47:58 2025 +1100 + + Be explicit about environment variables for tests. - OpenBSD-Commit-ID: eb7eb36371e1ac01050b32b70fb2b3e5d98e72f5 + This will make it easier to reproduce a test failure by cut-and-paste of + the corresponding line from the github log. -commit 579d9adb70ec0206a788eb5c63804c31a67e9310 -Author: naddy@openbsd.org -Date: Mon Jun 17 13:50:18 2024 +0000 +commit 77a3e6ba47381547b3fe4b29223256f276fbd07e +Author: Darren Tucker +Date: Fri Mar 28 16:46:40 2025 +1100 - upstream: remove one more mention of DSA + Add tcmalloc flags to TEST_SSH_SSHD_ENV. - OpenBSD-Commit-ID: 8515f55a15f02836ba657df341415f63c60526ca + This will get passed to sshd via test-exec.sh. -commit 7089b5f8436ef0b8d3d3ad9ce01045fb9e7aab15 +commit a73890e340fbd6121251854b658a72d738b86c84 Author: Darren Tucker -Date: Wed Jun 19 23:09:05 2024 +1000 +Date: Thu Mar 27 23:04:44 2025 +1100 - Move -f to the place needed to restart sshd. + Add PuTTY 0.81, 0.82 and 0.83 to tests. -commit d5f83cfd852b14a25f347f082ab539a9454702ad +commit 90a28de0d49570324d1695c0b4686354ef3bcae0 Author: Darren Tucker -Date: Wed Jun 19 21:04:01 2024 +1000 +Date: Thu Mar 27 22:30:40 2025 +1100 - Need to supply "-f" to restart sshd. + Include TCMALLOC_STACKTRACE_METHOD in output. + + If TCMALLOC_STACKTRACE_METHOD happens to be set, include it in the debug + output to make reproducing test cases easier. -commit fad34b4ca25c0ef31e5aa841d461b6f21da5b8c1 -Author: dtucker@openbsd.org -Date: Wed Jun 19 10:15:51 2024 +0000 +commit fd5a6bb6dd7657c4bd8cd0ee11d5c8ddf0d927b2 +Author: Darren Tucker +Date: Thu Mar 27 20:15:11 2025 +1100 - upstream: Provide defaults for ciphers and macs + Test with-linux-memlock-onfault in kitchensink. + +commit 22330711e2459c23d9736ee16e0e2ee0fcc30b9a +Author: Collin Funk +Date: Wed Mar 26 18:24:59 2025 -0700 + + Include fcntl.h so AT_FDCWD does not get redefined. + +commit 6c49e5f7dcaf886b4a702a6c003cae9dca04d3ea +Author: Daniil Tatianin +Date: Thu Feb 27 11:37:13 2025 +0300 + + Add support for locking memory on Linux - if querying for them fails since on some versions of Dropbear (at least - v2024.85) "-m help" doesn't seem to work. Enable all supported pubkey - algorithms in the server. + Linux wakes up kcompactd threads in order to make more contiguous memory + available on the system, it does this by migrating live movable pages + (actively modifying live processes' page tables and constantly flooding + them with page invalidation IPIs, which can be up to millions per + second), which causes the process to become unresponsive for up to + seconds or even minutes in some severe cases. In case of sshd, we want + to always be able to connect to the system, even if it's under heavy + kcompactd load. - OpenBSD-Regress-ID: 4f95556a49ee9f621789f25217c367a33d2745ca + Introduce an option to protect sshd and its children sessions from being + compacted by kcompactd (this works in cojunction with + compact_unevictable_allowed = 0). Note that we depend on MCL_ONFAULT + being available, which was introduced in linux 4.4. MCL_ONFAULT allows + the system to lock pages lazily, thus drastically reducing memory usage + of a locked process (without MCL_ONFAULT, every existing mapping in the + process is instantly write-faulted). -commit 5521060e35ada9f957cecdddc06d0524e75409ef -Author: dtucker@openbsd.org -Date: Wed Jun 19 10:10:46 2024 +0000 +commit fdc4853c5b1567934d43ab13282f03033cc21325 +Author: Daniil Tatianin +Date: Thu Feb 27 11:46:25 2025 +0300 - upstream: Use ed25519 keys for kex tests - - since that's supported by OpenSSH even when built without OpenSSL. - Only test diffie-hellman kex if OpenSSH is compiled with support for it. + platform: introduce a way to hook new session start - OpenBSD-Regress-ID: a5d09ef9bbd171f9e4ec73ed0d9eeb49a8878e97 + Previously this was possible via post_fork_child, but ever since sshd + was split into multiple binaries, this is now no longer possible becase + of execv. -commit dbd3b833f6e3815e58f2dc6e14f61a51bcd4d6bd +commit 1b311b6b17be81577514c38e8be4f5740d7df496 Author: dtucker@openbsd.org -Date: Wed Jun 19 10:08:34 2024 +0000 +Date: Wed Mar 19 06:11:15 2025 +0000 - upstream: Rework dropbear key setup + upstream: Prevent theoretical NULL deref in throughlocal_sftp. - to always generate ed25519 keys, other types only if OpenSSH has support - for the corresponding key type. + Coverity CID 405019, although at the moment it's not reachable. ok djm@ - OpenBSD-Regress-ID: 8f91f12604cddb9f8d93aa34f3f93a3f6074395d + OpenBSD-Commit-ID: 630d46c1021b69fbb470e349976c70e9a48b7644 -commit d6218504e11ae9148adf410fc69b0710a052be36 +commit 96493ebd6ff48bbb802576e208794a26928569b0 Author: Darren Tucker -Date: Wed Jun 19 20:20:24 2024 +1000 +Date: Wed Mar 19 17:35:10 2025 +1100 - Restart sshd after installing it for testing. - - When installing an sshd built without OpenSSL the mismatch between - the running sshd and newly installed sshd-session will cause the - remainder of the test to fail. + Fix workflow syntax again. -commit 786a4465b6bb702daf4fb17b7c3bcb42b52f0b46 +commit 575c43fd4c44d376b1771c0fdaf4941021ba88c9 Author: Darren Tucker -Date: Tue Jun 18 19:59:59 2024 +1000 +Date: Tue Mar 18 20:54:48 2025 +1100 - Remove macos-11 runner. - - Github is retiring them soon. + Differentiate logfiles better. -commit df1c72a55edbebac14363b57de66ac6a147ecc67 -Author: Damien Miller -Date: Wed Jun 19 09:34:34 2024 +1000 +commit 8a1294638f3a47d46263ea574fa85c8e115ea893 +Author: Darren Tucker +Date: Tue Mar 18 20:27:46 2025 +1100 - PAMServiceName may appear in a Match block + Fix another typo in workflow. -commit de1c2e70e5a5dc3c8d2fe04b24cc93d8ef6930e7 -Author: dtucker@openbsd.org -Date: Tue Jun 18 08:11:48 2024 +0000 +commit bd9e6bbcc864b3e10c4e11f5aec1b3a5e3a89b55 +Author: Darren Tucker +Date: Tue Mar 18 18:16:12 2025 +1100 - upstream: Re-enable ssh-dss tests + Fix syntax error in workflow. + +commit ce88a1bb4a2e6425752094f7a2eb4adfb0ca7971 +Author: Darren Tucker +Date: Tue Mar 18 18:13:14 2025 +1100 + + Identify each logfile while printing them. + +commit b58e429960c4791fc4e30bb7c70d1f77d538b546 +Author: djm@openbsd.org +Date: Tue Mar 18 04:53:14 2025 +0000 + + upstream: fix NULL dereference for Match conditions missing - ... if ssh is compiled with DSA support + arguments, e.g. "Match user". Spotted by Coverity (CID 477813) - OpenBSD-Regress-ID: bbfaf8c17f2b50a2d46ac35cb97af99b990c990d + OpenBSD-Commit-ID: 13584281cfa23b8ebc41f9d128a6b9464ae960d4 -commit dabc2c7cf3c141e8e5d5a1a60d6c1d2d2422cf43 -Author: anton@openbsd.org -Date: Tue Jun 18 06:14:27 2024 +0000 +commit 0ce5281f017c3ad7bdcc2bbd9745119a73e0cbb8 +Author: tb@openbsd.org +Date: Fri Mar 14 09:49:49 2025 +0000 - upstream: Stop using DSA in dropbear interop tests. + upstream: Fix EVP_CIPHER_CTX_ctrl() return checks - OpenBSD-Regress-ID: abfd4457d99d8cc1417fd22ca2c570270f74c1cf + While this API tries to translate negative return values (i.e. -1) to 0 + in BoringSSL and LibreSSL, it is still possible for it to return negative + values in prinicple. We even incorrectly document that -1 can be returned + while Boring and OpenSSL plead the Fifth. + + In OpenSSL 3 there are now code paths that explicitly return -1 and they + started shifting their return checks to <= 0 - of course they do this in + inconsistent and sometimes incorrect manner. While these paths aren't + reachable from ssh right now, who can really tell what happens in the two + hundred lines of inscrutable bloated mess this has become. + + So error check with <= 0 to ensure that we don't accidentally translate an + error to success. + + ok markus schwarze + + OpenBSD-Commit-ID: a855c833cf4ecfce43bedc761f26ad924f70483c -commit 761438012710169445acc179e3870c53c862bda0 -Author: Damien Miller -Date: Tue Jun 18 12:29:45 2024 +1000 +commit 2e81100763d5885e500f065b04c16ed87ce74318 +Author: Darren Tucker +Date: Mon Mar 17 21:35:55 2025 +1100 - missed a bit of DSA in the fuzzer + Fix debug log path. -commit 3f9cc47da588e8de520720e59f98438043fdaf93 +commit 442a44970179d70ebb62bba792699eaec978a1db +Author: Darren Tucker +Date: Fri Mar 14 16:24:06 2025 +1100 + + Also lazily unmount workspace in case of straggers. + +commit 20427f6735fe5ddab31911ce5315adc71acf47d8 +Author: Darren Tucker +Date: Fri Mar 14 16:17:39 2025 +1100 + + Make sure upstream tests run on correct hardware. + +commit 91a2f70a56827ae31649baf17227b0914ac5aa36 +Author: Darren Tucker +Date: Fri Mar 14 13:47:27 2025 +1100 + + Add OpenBSD upstream test on obsdsnap-arm64. + +commit c20f7413525602b0ea786d8974d03a81f7ca2a92 Author: Damien Miller -Date: Tue Jun 18 09:35:53 2024 +1000 +Date: Thu Mar 13 10:45:53 2025 +1100 - DSA support is disabled, so remove from fuzzers + rebuild .depend -commit 00eb95957dea5484b2c7c043f7d2bbc87301bef2 +commit d47ef958b89c6fa809302d654009d3dfabe11b75 Author: djm@openbsd.org -Date: Mon Jun 17 08:30:29 2024 +0000 +Date: Wed Mar 12 22:43:44 2025 +0000 - upstream: disable the DSA signature algorithm by default; ok + upstream: remove assumption that the sshd_config and any configs - markus@ + included from it can fit in a (possibly enlarged) socket buffer, by having + the sshd listener mainloop actively manage sending the configuration to the + sshd-session subprocess. - (yes, I know this expands to "the Digitial Signature Algorithm - signature algorithm) + work by markus@ w/ a little feedback from me; + ok me and committing on his behalf - OpenBSD-Commit-ID: 961ef594e46dd2dcade8dd5721fa565cee79ffed + OpenBSD-Commit-ID: 8f54451483f64951853074adb76bc4f838eaf3ae -commit 5603befe11c9464ea26fe77cbacc95a7cc0b1ea7 -Author: djm@openbsd.org -Date: Mon Jun 17 08:28:31 2024 +0000 +commit 9c90b563943c16418d737433ac478974b8761ee5 +Author: dtucker@openbsd.org +Date: Tue Mar 11 11:46:44 2025 +0000 - upstream: promote connection-closed messages from verbose to info + upstream: Prime caches for DNS names needed for tests. - log level; they could be the only record of the connection terminating if the - client doesn't send a SSH2_MSG_DISCONNECT message. ok dtucker@ + When running the SSHFP tests, particularly on an ephemeral VM, the first + query or two can fail for some reason, presumably because something isn't + fully initialized or something. To work around this, issue queries for the + names we'll need before we need them. - OpenBSD-Commit-ID: 0c8bfaf5e9fdff945cee09ac21e641f6c5d65d3c + OpenBSD-Regress-ID: 900841133540e7dead253407db5a874a6ed09eca -commit b00331402fe5c60d577f3ffcc35e49286cdc6b47 -Author: Damien Miller -Date: Mon Jun 17 17:02:18 2024 +1000 +commit 10124eefe875a3e4e1cfb84ebe6a613ed3213b78 +Author: dtucker@openbsd.org +Date: Tue Mar 11 09:06:50 2025 +0000 - propagate PAM crashes to PerSourcePenalties + upstream: Some dd's don't understand "1m", so handle seperately. - If the PAM subprocess crashes, exit with a crash status that will be - picked up by the sshd(8) listener process where it can be used by - PerSourcePenalties to block the client. This is similar handling to - the privsep preauth process. + OpenBSD-Regress-ID: 1d983b27c96f28f69d3a288c19e8d8c58e1b2ee3 -commit 1c207f456ace38987deda047758d13fbf857f948 -Author: Damien Miller -Date: Mon Jun 17 15:06:01 2024 +1000 +commit c21c8fc319376c2f5e0da166e9e89a97a245ae72 +Author: Darren Tucker +Date: Tue Mar 11 19:17:46 2025 +1100 - minix doesn't have loopback, so skip penalty tests + Lazily unmount github workspace at end of workflow. - pointed out by dtucker@ + Sometimes when a test times out the workspace is still busy when we try + to unmount it, which leaves the runner unusable until it's cleaned up + manually. We try to unmount this in the first step, but that usually + doesn't work since it fails during setup before it starts our workflow. + Move it to the end and make it a lazy unmount so it hopefully works + eventually. -commit 48443d202eaec52d4d39defdd709a4499a7140c6 -Author: djm@openbsd.org -Date: Sun Jun 16 11:54:49 2024 +0000 +commit 4bcbac742968f5086cfd4c570a51de25ef77931f +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:50:20 2025 +0000 - upstream: same treatment for this test + upstream: Add regress test for sftp resume. - OpenBSD-Regress-ID: d0cc9efca7833e673ea7b0cb3a679a3acee8d4c7 + OpenBSD-Regress-ID: 37f629b3014338fa23a85df1e1bb320ea12282e1 -commit 45562a95ea11d328c22d97bf39401cd29684fb1f -Author: djm@openbsd.org -Date: Sun Jun 16 08:18:06 2024 +0000 +commit e2c4f070b43a4fd7d59a9350e2fe78df605830b5 +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:46:02 2025 +0000 - upstream: penalty test is still a bit racy + upstream: Use ssh binary instead of the (smaller) script when - OpenBSD-Regress-ID: 90c9ac224db454637baf1ebee5857e007321e824 + preparing test data files since it's faster. + + OpenBSD-Regress-ID: 4215e42682fdb73e131e10645d4a1a23a91d64f5 -commit 8d0f7eb147ef72d18acb16c0b18672d44941a8ca -Author: djm@openbsd.org -Date: Sat Jun 15 03:59:10 2024 +0000 +commit 62f02e95ba5cda4649c482d30f4370e2360eb94d +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:43:45 2025 +0000 - upstream: crank up penalty timeouts so this should work on even the + upstream: Set up dbclient's known_hosts as it expects. - slowest of test builders + OpenBSD-Regress-ID: 9e0898e8423237ce5023be53787bb4062e0d0418 + +commit 395284bd52887dbaf7e78200c857d7f2d9ce398e +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:43:03 2025 +0000 + + upstream: Use $DBCLIENT to access dbclient for consistency. - OpenBSD-Regress-ID: 70bda39c83e3fc9d0f3c1fad4542ed33e173d468 + OpenBSD-Regress-ID: 81e1b41e1ffc49aba1e6fcaeb6242f3b7875ea3c -commit 93c75471a1202ab3e29db6938648d4e2602c0475 -Author: jmc@openbsd.org -Date: Fri Jun 14 05:20:34 2024 +0000 +commit 97e10c0005a784622c61cb4e8bb7858b410bbcc6 +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:42:08 2025 +0000 - upstream: sort -q in the options list; + upstream: Check if dbclient supports SHA1 before trying SHA1-based - OpenBSD-Commit-ID: 6839b38378f38f754de638a5e988c13b4164cc7c + KEX. + + Dropbear 2025.87 removed SHA1 support by default, which means + diffie-hellman-group14-sha1 is not available. Unfortunately there isn't a + flag to query supported KEX, so instead check MACs and if it doesn't have + SHA1 methods, assuming SHA1 based KEXes are likewise not available. Spotted + by anton@. + + OpenBSD-Regress-ID: acfa8e26c001cb18b9fb81a27271c3b51288d304 -commit dd7807bbe80a93ffb4616f2bd5cf83ad5a5595fb -Author: djm@openbsd.org -Date: Fri Jun 14 05:01:22 2024 +0000 +commit 29a5127f808d00aa539fd27d83a65c2c56179b0e +Author: dtucker@openbsd.org +Date: Tue Mar 11 07:48:51 2025 +0000 - upstream: clarify KEXAlgorithms supported vs available. Inspired by + upstream: Set highwater when resuming a "put". Prevents bogus "server - bz3701 from Colin Watson. + reordered acks" debug message. ok djm@ - OpenBSD-Commit-ID: e698e69bea19bd52971d253f2b1094490c4701f7 + OpenBSD-Commit-ID: aa7f6d0fc2e893c8c278ea3e6e0974c2eca83f5d -commit d172ad56df85b68316dbadbedad16761a1265874 -Author: djm@openbsd.org -Date: Fri Jun 14 05:00:42 2024 +0000 +commit 6575859d7acb110acf408707f98ed9744ca7d692 +Author: dtucker@openbsd.org +Date: Mon Mar 3 06:54:37 2025 +0000 - upstream: ssh-keyscan -q man bits + upstream: Test for %-token and env var expansion in SetEnv. - OpenBSD-Commit-ID: ba28d0e1ac609a4c99c453e57e86560c79079db1 + OpenBSD-Regress-ID: bd6139a6177ac4afb29a0ce4afc23567b22ef9f9 -commit 092e4ff9ccaacbe035f286feb1b56ed499604743 -Author: Damien Miller -Date: Fri Jun 14 14:46:35 2024 +1000 +commit fd7ad8d7bf7dbdeb8f11a8b51aa9d31df1a17e52 +Author: dtucker@openbsd.org +Date: Sun Mar 2 07:41:06 2025 +0000 - skip penalty-expire test in valgrind test env + upstream: Also test User expansions when supplied via -l option and + + user@host. + + OpenBSD-Regress-ID: 56415859260b53ef0dd20f71225ba5fdf6320f50 -commit 2866ad08a9c50d7b67ce9424ca990532b806a21a +commit e6cfd783f1491b502db9322aa970822c63f1667d +Author: dtucker@openbsd.org +Date: Sat Mar 1 06:12:47 2025 +0000 + + upstream: Tests for User expansion of %-tokens and environment + + variables. + + OpenBSD-Regress-ID: 7ed21dd0e09fb1f3537b8b177f171018aa501628 + +commit 197e503b8e4b642ce0f405a5d65da4256fa96431 Author: djm@openbsd.org -Date: Fri Jun 14 04:43:11 2024 +0000 +Date: Fri Dec 6 16:25:58 2024 +0000 - upstream: split the PerSourcePenalties test in two: one tests penalty + upstream: use glob(3) wildcards in AuthorizedKeys/PrincipalsFile - enforcement but not penalty expiry, the other tests penalty expiry. + tests to exercise this feature; ok dtucker - This lets us disable the expiry testing in certain CI test environments. + OpenBSD-Regress-ID: 7f7b19c0b05b1862cc6521ce61b2b301a3f9cc3b + +commit 396202180180a4ac16788d469508a348789dafa1 +Author: djm@openbsd.org +Date: Fri Dec 6 10:37:42 2024 +0000 + + upstream: implement attestation verification for ED25519 keys - OpenBSD-Regress-ID: f56811064f3e3cb52ee73a206b8c2a06af1c8791 + OpenBSD-Regress-ID: c44fa5cdb434375a8b5545fdb4fc651061afca1f -commit b2c64bc170d75823622a37cab3ca1804ca87ad16 -Author: Damien Miller -Date: Fri Jun 14 14:19:23 2024 +1000 +commit b49875428cda9c16c5bd52552100da2b419cda5f +Author: dtucker@openbsd.org +Date: Mon Mar 3 06:53:09 2025 +0000 - add a sshd_config PamServiceName option + upstream: Add %-token and environment variable expansion to SetEnv. - Allows selecting which PAM service name to use when UsePAM is - enabled. Defaults to "sshd" unless overridden at compile time - by defining SSHD_PAM_SERVICE. + feedback deraadt@ jmc@, nits and ok djm@ - bz2102, ok dtucker@ + OpenBSD-Commit-ID: 2f6e5070481cb73e6f35fd1c6608c1eeff88a5c1 -commit 9f032a4dd17bf0ae6066223d82aa5e784285d987 +commit b6bba67e6c31d268480773e4fed16d0a32b4218e Author: djm@openbsd.org -Date: Fri Jun 14 00:26:12 2024 +0000 +Date: Sun Mar 2 22:44:00 2025 +0000 - upstream: don't redirect stderr for ssh-keyscan we expect to succeed + upstream: fix PerSourcePenalty incorrectly using "crash" penalty when - OpenBSD-Regress-ID: 8878b8eb4e070ed2e343166d3eb86db4a08a216c + LoginGraceTime was exceeded. Reported by irwin AT princeton.edu via bz3797 + + OpenBSD-Commit-ID: 1ba3e490a5a9451359618c550d995380af454d25 -commit 1e84d0cf40e94ae3a77d6a7ca8c036d8e3d55a40 +commit 38d69fee1b06948f160d94abd07b6b297630d30a +Author: Damien Miller +Date: Sun Mar 2 22:06:53 2025 +1100 + + include __builtin_popcount replacement function + + Some systems/compilers lack __builtin_popcount(), so replace it as + necessary. Reported by Dennis Clarke; ok dtucker@ + +commit c94138d02a45dda5015f38f5a60b0bdde29019c1 Author: djm@openbsd.org -Date: Fri Jun 14 00:25:25 2024 +0000 +Date: Sun Mar 2 11:03:13 2025 +0000 - upstream: make host/banner comments go to stderr instead of stdout, + upstream: whitespace - so they are useful as comments without extra shell redirection and so they - don't clutter actual errors on stderr. + OpenBSD-Commit-ID: 1bd8953a37451ef7e0991f9fceec5e8005fe986a + +commit 65d2c59628e68e166046efa69e76c1d395a8df6e +Author: dtucker@openbsd.org +Date: Sun Mar 2 07:02:49 2025 +0000 + + upstream: Make a copy of the user when handling ssh -l, so that - Add a -q flag to shut them up. + later during User token expansion we don't end up freeing a member of argv. + Spotted by anton@'s regress tests. - ok dtucker@ + OpenBSD-Commit-ID: 2f671a4f5726b66d123b88b1fdd1a90581339955 + +commit bd30cf784d6e825ef71592fb723c41d4f2fd407b +Author: dtucker@openbsd.org +Date: Sat Mar 1 06:11:26 2025 +0000 + + upstream: Allow %-token and environment variable expansion in User, - OpenBSD-Commit-ID: bec813de56a71adb5c1a76adcf49621130d24264 + with the exception of %r and %C which are self-referential. Requested in + bz#3477, ok djm@, man page improvements jmc@ + + OpenBSD-Commit-ID: caeb46251ee073662f6f5864c6f7b92d8ac80fa8 -commit 3e806d011855d6bd648ec95b9df630ebbd11c3bf -Author: naddy@openbsd.org -Date: Thu Jun 13 15:06:33 2024 +0000 +commit 94f59dcfc57f95ae044f75c3ce544329c8956c35 +Author: Darren Tucker +Date: Sat Mar 1 10:28:59 2025 +1100 - upstream: separate keywords with comma + Rebuild config files if Makefile changes. - OpenBSD-Commit-ID: d65a99666202a8188c4991c18d14374a229f7be5 + This ensures paths are updated if they are changed by re-running configure. + Patch from rapier at psc.edu. -commit abfd1f7a3cbd0a92581a0febba254b2f6649c0d9 +commit dfd9880585db1570656022f9fe1519df673f7b8a +Author: Darren Tucker +Date: Wed Feb 26 18:16:03 2025 +1100 + + Check for le32toh, le64toh, htole64 individually. + + It appears that at least some versions of endian.h in glibc do not have + the latter two, so check for and replace each one individually. + bz#3794, ok djm@ + +commit cb99e8eb228df366af33f4fe88d7a9dd0dbf0756 Author: djm@openbsd.org -Date: Fri Jun 14 00:23:55 2024 +0000 +Date: Tue Feb 25 06:25:30 2025 +0000 - upstream: specify an algorithm for ssh-keyscan, otherwise it will make + upstream: ressurect fix for "match invalid-user" that got clobbered - multiple attempts simultaneously and confuse the test + by 1.423 - OpenBSD-Regress-ID: 6e910f3315c4345053db1bf5cbf61826b194d0b9 + OpenBSD-Commit-ID: d18bf0945976e0f3467d710d4bc8bdbe181c0567 -commit a8fbe2f7d0d96d299ee8e69769e3b51067978748 -Author: Damien Miller -Date: Thu Jun 13 16:41:29 2024 +1000 +commit 487cf4c18c123b66c1f3f733398cd37e6b2ab6ab +Author: deraadt@openbsd.org +Date: Fri Feb 21 18:22:41 2025 +0000 - sshd: don't use argv[0] as PAM service name - - sshd would implicitly use argv[0] as the PAM service name to - allow people to select different PAM service names by making - differently-named copies/links to the sshd binary. + upstream: Also prohibit , (comma) in hostnames, proposed by David - Splitting sshd into sshd/sshd-session broke this, as the process - that starts PAM is always sshd-session and the user has no control - over this. + Leadbeater ok djm millert - Hardcode "sshd" as the default PAM service name unless/until we - figure out a better way. Should unbreak OSX integration tests. + OpenBSD-Commit-ID: 2837fa31dc6e81976f510f0a259edaa559b20b07 -commit bf204bd05c3ae650f87e2b96527688579f59774c +commit 3bc6de98c830bd5207f6c371ba69c5874f06305b Author: Damien Miller -Date: Thu Jun 13 15:00:28 2024 +1000 +Date: Mon Feb 24 17:27:50 2025 +1100 - prepare for checking in autogenerated files + Try to fix github tcmalloc target failure - We plan to check in automatically generated files (config.h.in, etc) on - release branches. These files are normally ignored by .gitignore, but - this shuffles the contents of this file to make it easy to un-ignore - them. + tcmalloc may, depending on the stacktrace generator it uses, create + pipe(2) fds during shared library initialisation. These will later + get clobbered by ssh/sshd calling closefrom() and chaos will ensue. + Tell tcmalloc to use an unwinder that doesn't pull this stuff. -commit 425f79a837489904c343b349ef00e09aeaa4e752 +commit 922e54bbfe8c8479453693ef52350338f0c19124 Author: Damien Miller -Date: Thu Jun 13 14:41:33 2024 +1000 +Date: Fri Feb 21 13:44:35 2025 +1100 - typo in comment + cleanup last mention of ubuntu-20.04 -commit afe10313c1fa8d478af399ee7d54c8f85503013b +commit bc4b3f6dc1738d389e5c9dcca8c56d7e153fee49 Author: Damien Miller -Date: Thu Jun 13 14:35:25 2024 +1000 +Date: Fri Feb 21 13:44:13 2025 +1100 - fix PTY allocation on Cygwin, broken by sshd split - - Cygwin doesn't support FD passing and so used to disable post-auth - privilege separation entirely because privsep requires PTY allocation - to happen in the privileged monitor process with the PTY file - descriptors being passed back to the unprivileged process. + prune gcc/clang versions to be tested - This brings back a minimal version of the previous special treatment - for Cygwin (and any other platform that sets DISABLE_FD_PASSING): - privilege separation remains enabled, but PTY allocation happens in - the post-auth user process rather than the monitor. - - This either requires PTY allocation to not need privilege to begin - with (this appears to be the case on Cygwin), or the post-auth - privsep process retain privilege (other platforms that set the - DISABLE_FD_PASSING option). + Test only the oldest and latest versions of each + +commit 94b73755f931d592a612ef5cb998694643eab5ff +Author: Damien Miller +Date: Fri Feb 21 11:30:22 2025 +1100 + + Update AWS-LC version number - Keeping privileges here is bad, but the non-Cygwin systems that set - DISABLE_FD_PASSING are so deeply legacy that this is likely to be the - least of their problems. + Patch from Shubham Mittal bz bz3792 -commit f66d4df5749551380a8c4ae642347675a0b6a2e9 +commit 6887099fae6d9f3482e1075d034e9343dc413200 Author: Damien Miller -Date: Thu Jun 13 11:33:09 2024 +1000 +Date: Fri Feb 21 11:22:34 2025 +1100 - delay lookup of privsep user until config loaded + adjust workflows for ubuntu version transition - sshd-session attempting to use options.kerberos_authentication to - decide whether it needed to lookup the privsep user before the - configuration was loaded. This caused it to get a placeholder value - that caused it always to try to lookup the privsep user, breaking at - least one test environment. + remove workflows for unsupported compilers, add a few for additional + supported compilers, move some workflows to run on ubuntu-latest -commit f1c42858b94f5d9b58867b34dce3afb39c6b56a8 +commit 33bb47e6f74f2ca8093946e6f462d655a9ae46d3 Author: Damien Miller -Date: Thu Jun 13 11:16:57 2024 +1000 +Date: Thu Feb 20 17:10:32 2025 +1100 - missing file for PerSourcePenalties regress test + Add ubuntu-*-arm test runners -commit 4de80ff4e6fab5a6bb0028e7d57c6c23d1485adb -Author: djm@openbsd.org -Date: Wed Jun 12 22:36:00 2024 +0000 +commit a0c95fbb215b2168fa51b15906e2d6990d7fef6b +Author: Damien Miller +Date: Thu Feb 20 17:03:28 2025 +1100 - upstream: split PerSourcePenalties address tracking. Previously it - - used one shared table and overflow policy for IPv4 and IPv6 addresses, now it - will use separate tables and optionally different overflow policies. - - This prevents misbehaviour from IPv6 addresses (which are vastly easier - to obtain many of) from affecting IPv4 connections and may allow for - stricter overflow policies. + remove ubuntu-20.04 Github action runners - ok deraadt@ + ubuntu-20.04 is deprecated now, so migrate all its unique runners + to ubuntu-22.04. - OpenBSD-Commit-ID: 12637ed0aa4d5f1f3e702da42ea967cbd8bfdfd9 + ok dtucker@ -commit 06ab4c6931b0aaa4334db2faaa7e1069e76d0df6 -Author: jmc@openbsd.org -Date: Tue Jun 11 05:24:39 2024 +0000 +commit 0cbeedba81b57c56379e1d202b9ccd3b72af7ddc +Author: Damien Miller +Date: Tue Feb 18 19:03:42 2025 +1100 - upstream: do not mark up "(default: 20ms)"; - - OpenBSD-Commit-ID: 54151ecdecfa1b67dcdda4fd24826ef6e2148ad4 + openssh-9.9p2 -commit cfe243cd9fde148ed060637876e27bb55ac78be9 +commit 0832aac79517611dd4de93ad0a83577994d9c907 Author: djm@openbsd.org -Date: Tue Jun 11 02:54:51 2024 +0000 +Date: Tue Feb 18 08:02:48 2025 +0000 - upstream: reap preauth net child if it hangs up during privsep message + upstream: Fix cases where error codes were not correctly set - send, not just message receive + Reported by the Qualys Security Advisory team. ok markus@ - OpenBSD-Commit-ID: 02a093f4ab4f8f83f0cd1ea2bb35b9ca420448f0 + OpenBSD-Commit-ID: 7bcd4ffe0fa1e27ff98d451fb9c22f5fae6e610d -commit b0a711c00b9c64afd1c9d6fb538275c6604a2676 +commit 6ce00f0c2ecbb9f75023dbe627ee6460bcec78c2 Author: djm@openbsd.org -Date: Tue Jun 11 01:58:27 2024 +0000 +Date: Tue Feb 18 08:02:12 2025 +0000 - upstream: fix PIDFILE handling, broken for SUDO=doas in last commit + upstream: Don't reply to PING in preauth phase or during KEX - here + Reported by the Qualys Security Advisory team. ok markus@ - OpenBSD-Regress-ID: 96fec579af228f87a036e94801eb294af9074625 + OpenBSD-Commit-ID: c656ac4abd1504389d1733d85152044b15830217 -commit 90fb801e2d9241be50a2a7ff79428386442a041f -Author: djm@openbsd.org -Date: Tue Jun 11 02:00:30 2024 +0000 +commit 9e5bd74a85192c00a842f63d7ab788713b4284c3 +Author: jmc@openbsd.org +Date: Sat Feb 15 06:48:56 2025 +0000 - upstream: reap the pre-auth [net] child if it hangs up during privsep + upstream: - use \& when contructs like "e.g." end a line, to avoid - message sending, not just receiving + double spacing - macro is Qq not Oq - OpenBSD-Commit-ID: f7341605bf08c4c15830910446e6775323f2f8cb + OpenBSD-Commit-ID: 17e5d2d7f288cc7fc536e3af252224525f9fb43a -commit ef878d58798f6688c7f4d4e417dc0c29023ea831 -Author: djm@openbsd.org -Date: Tue Jun 11 01:23:25 2024 +0000 +commit f519e71fb7a46314ae16e2a75490649dc0bd01a2 +Author: Damien Miller +Date: Sat Feb 15 13:12:40 2025 +1100 - upstream: a little more RB_TREE paranoia - - OpenBSD-Commit-ID: 8dc2fd21eebd8830c4a4d25461ac4fe228e11156 + depend -commit fc4e96b2174d6a894d2033421699d091679baced +commit 9131ac64b0ebe66dc1de9d44bf8d1bd64a24c350 Author: djm@openbsd.org -Date: Tue Jun 11 01:22:25 2024 +0000 +Date: Sat Feb 15 01:52:07 2025 +0000 - upstream: fix off-by-one comparison for PerSourcePenalty + upstream: add "Match version" support to ssh_config. Allows - OpenBSD-Commit-ID: af4f5d01c41ef870b23e55655bfbf73474a6c02b + matching on the local version of OpenSSH, e.g. "Match version OpenSSH_10.*" + + ok markus@ + + OpenBSD-Commit-ID: c0cb504d0b9e43ccf12e68a544a7cd625e89758d -commit 82c836df4ff41145553cd7adb11c5b985aeaa06f +commit 192a20df00c8a56fe7d92ffa23d959c865d7fb9e Author: djm@openbsd.org -Date: Tue Jun 11 01:21:41 2024 +0000 +Date: Sat Feb 15 01:50:47 2025 +0000 - upstream: move tree init before possible early return + upstream: Add support for "Match sessiontype" to ssh_config. Allows - OpenBSD-Commit-ID: 72e2c5b69f151c08a7c5bf5ad929b97a92c273df + matching on the type of session requested, either "shell" for interactive + sessions, "exec" for command execution sessions, "subsystem" for subsystem + requests, such as sftp, or "none" for transport/forwarding-only sessions. + + ok markus@ + + OpenBSD-Commit-ID: eff5c001aecb2283d36639cfb28c0935a8bfd468 -commit a2300f015cc4939c4d9c564b58b74e71202dc978 +commit caa3c0c77082888236b0b0c4feb3e6879731b3ba Author: djm@openbsd.org -Date: Tue Jun 11 01:07:35 2024 +0000 +Date: Sat Feb 15 01:48:30 2025 +0000 - upstream: update to mention that PerSourcePenalties default to + upstream: "Match command ..." support for ssh_config to allow - being enabled and document the default values for each parameter. + matching on the remote command specified on the commandline. - OpenBSD-Commit-ID: b981288bddfb097aad269f62df4081c688ce0034 + Also relaxes matching rules for `Match tagged` to allow + `Match tagged ""` to match an empty tag value. This also works + for command. + + ok markus@ + + OpenBSD-Commit-ID: 00dcfea425bf58d824bf5e3464cfc2409121b60d -commit 41987efd356d3fc30139aeab4b09374acf8f91a0 +commit 38f6000e9851a00e2e4b8e1eb4ea6a243ef7e6a3 +Author: Damien Miller +Date: Tue Feb 11 10:32:26 2025 +1100 + + depend + +commit aa1409e7a0a5605f0127651a3ba5a348666325bc Author: djm@openbsd.org -Date: Tue Jun 11 00:44:52 2024 +0000 +Date: Mon Feb 10 23:19:26 2025 +0000 - upstream: reap the [net] child if it hangs up while writing privsep + upstream: include arguments the command was invoked with, and - message payloads, not just the message header + operating system name, version and architecture in startup debugging output; + ok dtucker - OpenBSD-Commit-ID: 24dbd400aa381ac96be7ed2dd49018487dfef6ce + OpenBSD-Commit-ID: 2a509d319aaf31a6bf9998e1842832883fbc3edd -commit 6211aa085fa91155a24922e5329576ac9a8f3175 +commit 857ac20f5fe19f183defba5dbf4b7d9e6400230c Author: djm@openbsd.org -Date: Tue Jun 11 00:40:21 2024 +0000 +Date: Mon Feb 10 23:16:51 2025 +0000 - upstream: log waitpid() status for abnormal exits + upstream: include line number in Match debug messages, makes it a - OpenBSD-Commit-ID: b317930e06b51819c1a2bc6a4359764fecfb1c2d + little easier to see what's going on + + OpenBSD-Commit-ID: 1fcf4aa2ee667711b9497ded0fa52d757c69b1df -commit a59634c7adb9ae988748d99963dfafb3070d8d41 +commit af49d474e481d2d78b2f06b06a06b0b37629358e Author: djm@openbsd.org -Date: Tue Jun 11 00:36:20 2024 +0000 +Date: Mon Feb 10 23:00:29 2025 +0000 - upstream: correct error message + upstream: fix "Match invalid-user" from incorrectly being activated - OpenBSD-Commit-ID: 581f60f73099083392887206860229ab104620ed + in initial configuration pass when no other predicates were present on the + match line + + OpenBSD-Commit-ID: 02703b4bd207fafd03788bc4e7774bf80be6c9a8 -commit fa7d7a667f2ee031e72873e36de2d2a36bca973b -Author: deraadt@openbsd.org -Date: Fri Jun 7 13:23:30 2024 +0000 +commit 1c67bae3f5834e48ded71c406f2039dea6e536db +Author: schwarze@openbsd.org +Date: Sun Feb 9 18:24:08 2025 +0000 - upstream: avoid shadowing issues which some compilers won't accept + upstream: In a section 1 manual, use the plain English words - ok djm + "standard output" rather than the overly technical abbreviation "stdout" - we + are not talking about a device file or a FILE * object here. Issue reported + by on the groff mailing list. - OpenBSD-Commit-ID: 1e89572397dda83433d58c4fa6333a08f51170d4 + OpenBSD-Commit-ID: a0816999f970e6159523bed8484f62c42ec93109 -commit 3ad4cd9eeca5c9bc6706db44b6de88e2e4513fd6 -Author: jmc@openbsd.org -Date: Thu Jun 6 21:14:49 2024 +0000 +commit 85b3d68dd931416ede657f371f1d60cdc3a66f34 +Author: dtucker@openbsd.org +Date: Fri Jan 17 00:09:41 2025 +0000 - upstream: escape the final dot at eol in "e.g." to avoid double + upstream: Fix debug logging of user specific delay. Patch from - spacing; + Achim Leitner (fjl5) via github PR#552. - OpenBSD-Commit-ID: 0a9fb10bc9f7d577afe2da3f498a08bc431115b9 + OpenBSD-Commit-ID: 834a869ed9b15058d3c1ef0cd75402ef989255d8 -commit 0e0c69761a4c33ccd4a256560f522784a753d1a8 -Author: djm@openbsd.org -Date: Thu Jun 6 20:25:48 2024 +0000 +commit e4e5b06fdf4532705669c0ae944b364022d16b9d +Author: dtucker@openbsd.org +Date: Thu Jan 16 06:37:10 2025 +0000 - upstream: enable PerSourcePenalties by default. + upstream: Call log_init in sshd-auth and sshd-session immediately - ok markus + after parsing the config file so that any log settings set in the config file + take effect immediately. Move version banners to immediately after that, and + make them distinct per binary. ok djm@ - NB. if you run a sshd that accepts connections from behind large NAT - blocks, proxies or anything else that aggregates many possible users - behind few IP addresses, then this change may cause legitimate traffic - to be denied. + OpenBSD-Commit-ID: acf3d090638edf9b6e6f78eed96b537fe671f0f5 + +commit 0643994b20f2cc54bca80842a984b3052ff1a6a9 +Author: dtucker@openbsd.org +Date: Wed Jan 15 22:23:13 2025 +0000 + + upstream: Use strprefix helper when processing sshd -C test args - Please read the PerSourcePenalties, PerSourcePenaltyExemptList and - PerSourceNetBlockSize options in sshd_config(5) for how to tune your - sshd(8) for your specific circumstances. + instead of counting bytes by hand. ok djm@ - OpenBSD-Commit-ID: 24a0e5c23d37e5a63e16d2c6da3920a51078f6ce + OpenBSD-Commit-ID: 2866d369d96fe04bf76112260ac37e489f98a9a9 -commit bd1f74741daabeaf20939a85cd8cec08c76d0bec -Author: djm@openbsd.org -Date: Thu Jun 6 20:20:42 2024 +0000 +commit 66efd0fbb6b8b95f8a520f2cdf8ede14e62b30b3 +Author: Damien Miller +Date: Thu Feb 6 09:38:09 2025 +1100 - upstream: mention that PerSourcePenalties don't affect concurrent + add support for AWS-LC (AWS libcrypto) - in-progress connections. + Patch from Shubham Mittal via bz3784; ok dtucker + +commit 826483d51a9fee60703298bbf839d9ce37943474 +Author: Tim Rice +Date: Mon Dec 16 15:36:54 2024 -0800 + + fix old typo (s/SYSVINITSTOPT/SYSVINITSTOP/) + +commit 1a8ce460f1d0c3f7304edba0733783b57b430e21 +Author: dtucker@openbsd.org +Date: Thu Dec 12 09:09:09 2024 +0000 + + upstream: Plug leak on error path, spotted by Coverity. ok djm@ - OpenBSD-Commit-ID: 20389da6264f2c97ac3463edfaa1182c212d420c + OpenBSD-Commit-ID: b1859959374b4709569760cae0866d22a16606d3 -commit 9774b938578327d88a651f4c63c504809717590a +commit 924f996144fc0ae1a659fadcfc2237d1ae935fc4 +Author: Xavier Hsinyuan +Date: Mon Dec 9 11:21:05 2024 +0800 + + Add $(srcdir) for standalone sk-libfido2 make target. + + Fix out-of-tree build failure due to incorrect path for `sk-usbhid.c`. + +commit bbc9c18e84de29c83fa03e69290979fcca54a2b2 Author: djm@openbsd.org -Date: Thu Jun 6 19:49:25 2024 +0000 +Date: Sat Dec 7 10:12:19 2024 +0000 - upstream: regress test for PerSourcePenalties + upstream: replace bespoke logging of MaxSessions enforcement with - OpenBSD-Regress-ID: a1af13d411b25a727742644459d26480b9a1b0f1 + new ratelimited logging infrastructure. + + Add ratelimits to logging of connections dropped by PerSourcePenalties + + ok dtucker + + OpenBSD-Commit-ID: f22fe7c39607e4361aadf95e33773ffd68c59489 -commit b8ebd86cefe9812204a10c028dc90de29918667d +commit 5a6ddf946cf105189c2c99a04f86ce95edc55fc5 Author: djm@openbsd.org -Date: Thu Jun 6 19:48:40 2024 +0000 +Date: Sat Dec 7 10:05:36 2024 +0000 - upstream: make sure logs are saved from sshd run via start_sshd + upstream: add infrastructure for ratelimited logging; feedback/ok - OpenBSD-Regress-ID: de4ef0e32e3ab85ff3a6c36eb08d1909c0dd1b4a + dtucker + + OpenBSD-Commit-ID: 18a83e5ac09d59aaf1e834fd6b796db89dd842e7 -commit d7b2070bdaa4ebbfafb9975c1d5a62b73289d31f +commit 85f0c1e75e8f6c5d83b8070918ee2f6ab16d403e Author: djm@openbsd.org -Date: Thu Jun 6 19:47:48 2024 +0000 +Date: Fri Dec 6 16:24:27 2024 +0000 - upstream: simplify + upstream: allow glob(3) patterns for sshd_config AuthorizedKeysFile - OpenBSD-Regress-ID: 50316e0d1ae0c0a057a45af042253e54ce23d11c + and AuthorizedPrincipalsFile directives; bz2755 ok dtucker + + OpenBSD-Commit-ID: 3e3e05a17fca39bba78b993a07b44664519adf7f -commit e6ea3d224513b6bfb93818809d4c7397f5995ba2 +commit 9a9ffee6e10bcd039f1f9385599577441ebe542a Author: djm@openbsd.org -Date: Thu Jun 6 18:48:13 2024 +0000 +Date: Fri Dec 6 16:21:48 2024 +0000 - upstream: prepare for PerSourcePenalties being enabled by default + upstream: support VersionAddendum in the client, mirroring the - in future + option of the same name in the server; bz2745 ok dtucker@ - OpenBSD-Regress-ID: 5236c6d1c823997aac5a35e2915da30f1903bec7 + OpenBSD-Commit-ID: 6ff7905b3f9806649bde750515786553fb89cdf4 -commit c0cb3b8c837761816a60a3cdb54062668df09652 +commit 41ab0ccecd68232e196efae5e224b31ca104c423 Author: djm@openbsd.org -Date: Thu Jun 6 19:50:01 2024 +0000 +Date: Fri Dec 6 16:02:12 2024 +0000 - upstream: disable stderr redirection before closing fds + upstream: clarify encoding of options/extensions; bz2389 - OpenBSD-Commit-ID: d42cb895ee4542098050367fc35321c9303f003a + OpenBSD-Commit-ID: c4e92356d44dfe6d0a4416deecb33d1d1eba016c -commit 81c1099d22b81ebfd20a334ce986c4f753b0db29 +commit 5488810359f0fd91e2f7b919c70a3798e46376cb Author: djm@openbsd.org -Date: Thu Jun 6 17:15:25 2024 +0000 +Date: Fri Dec 6 15:17:15 2024 +0000 - upstream: Add a facility to sshd(8) to penalise particular + upstream: ignore SIGPIPE here; some downstreams have had this for - problematic client behaviours, controlled by two new sshd_config(5) options: - PerSourcePenalties and PerSourcePenaltyExemptList. + years... - When PerSourcePenalties are enabled, sshd(8) will monitor the exit - status of its child pre-auth session processes. Through the exit - status, it can observe situations where the session did not - authenticate as expected. These conditions include when the client - repeatedly attempted authentication unsucessfully (possibly indicating - an attack against one or more accounts, e.g. password guessing), or - when client behaviour caused sshd to crash (possibly indicating - attempts to exploit sshd). + OpenBSD-Commit-ID: 73674ee4f8ceb8fc9cb8de71d8ddea0c721eb035 + +commit 4389a792d9078212366eba124a3eed36e009d09e +Author: djm@openbsd.org +Date: Fri Dec 6 15:12:56 2024 +0000 + + upstream: sync -o option lists with ssh.1; requested jmc@ - When such a condition is observed, sshd will record a penalty of some - duration (e.g. 30 seconds) against the client's address. If this time - is above a minimum threshold specified by the PerSourcePenalties, then - connections from the client address will be refused (along with any - others in the same PerSourceNetBlockSize CIDR range). + OpenBSD-Commit-ID: a7ac295b444da7b2ca7a33a52370594f6897f6bb + +commit 6b9cd095565ddc5402d5096dce248fa0521dbda3 +Author: Fabio Pedretti +Date: Mon Oct 16 17:12:24 2023 +0200 + + Remove ancient RHL 6.x config in RPM spec. - Repeated offenses by the same client address will accrue greater - penalties, up to a configurable maximum. A PerSourcePenaltyExemptList - option allows certain address ranges to be exempt from all penalties. + It looks like build6x options were intended for RHL 6.x + (the Red Hat distro predating Fedora, not RHEL), but were + then applied to RHEL. - We hope these options will make it significantly more difficult for - attackers to find accounts with weak/guessable passwords or exploit - bugs in sshd(8) itself. + Completely remove support for this ancient configuration. - PerSourcePenalties is off by default, but we expect to enable it - automatically in the near future. + Successfully built, installed and run on RHEL 6. This also + remove a build warning about deprecation of PreReq. + +commit 5cacfa798f92b707491375fed748d1d1bcb33ec9 +Author: Darren Tucker +Date: Fri Dec 6 23:54:45 2024 +1100 + + Add new hardware-backed signing key for myself. - much feedback markus@ and others, ok markus@ + Retire old non-hardware based signing key. + +commit f129b6ee1d4361799e65307216e3a4d5544356b7 +Author: Jonas 'Sortie' Termansen +Date: Sat Nov 2 22:05:45 2024 +0100 + + Fix configure implicit declaration and format warnings. + +commit 11a5e5179077f73c2d45bcdf3f60153ae3f17815 +Author: dtucker@openbsd.org +Date: Fri Dec 6 07:05:54 2024 +0000 + + upstream: Expand $SSH to absolute path if it's not already. - OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca + Prevents problem later in increase_datafile_size if ssh is not in + the path. Patch from quaresmajose via GHPR#510. + + OpenBSD-Regress-ID: 2670a66af8b827410ca7139f0a89f4501cece77b -commit 916b0b6174e203cf2c5ec9bcf409472eb7ffbf43 -Author: Damien Miller -Date: Fri Jun 7 03:31:02 2024 +1000 +commit dc2ef8f0944a4ff7ba19e52fd17b4654e6bd9b93 +Author: dtucker@openbsd.org +Date: Fri Dec 6 06:55:28 2024 +0000 - whitespace + upstream: Change "login again" to "log in again" + + in password change message. From ThinLinc-Zeijlon via github PR#532. + + OpenBSD-Commit-ID: fea5e9bc04caf613a118c419f16863733b340cf1 -commit 49b55e44182b8294419aa580cbf043d5b9e3d953 -Author: deraadt@openbsd.org -Date: Tue Jun 4 15:14:45 2024 +0000 +commit 8252f346eb21cd6b30816f905b7d94f10962373e +Author: naddy@openbsd.org +Date: Thu Dec 5 22:45:03 2024 +0000 - upstream: enable -fret-clean on amd64, for libc libcrypto ld.so + upstream: catch up documentation: AES-GCM is preferred to AES-CTR - kernel, and all the ssh tools. The dynamic objects are entirely ret-clean, - static binaries will contain a blend of cleaning and non-cleaning callers. + OpenBSD-Commit-ID: 63360924b6834507fe70020edb936f5075043a9e + +commit 9a2f4c75081769bd45eba2bf3fab0a32b25f1879 +Author: Darren Tucker +Date: Fri Dec 6 17:56:17 2024 +1100 + + Change text from "login to" to "log in to". - OpenBSD-Commit-ID: 112aacedd3b61cc5c34b1fa6d9fb759214179172 + From ThinLinc-Zeijlon via GHPR#532. -commit cc80d51d034bcb24fd0f2564a4bdf1612000a2a2 -Author: Damien Miller -Date: Wed Jun 5 02:21:30 2024 +1000 +commit 24dcf368d816b06136a02845ebd0c7846bf18927 +Author: Xavier Hsinyuan +Date: Fri Dec 6 11:56:34 2024 +0800 - remove PRIVSEP macros for osx + Fix configure message typo in sk-libfido2 standalone. -commit 8785491123d4d722b310c20f383570be758f8263 -Author: djm@openbsd.org -Date: Sat Jun 1 07:03:37 2024 +0000 +commit 1a0cac2f3411a22d69ae6918eff48456b805e73b +Author: Alexander Kanavin +Date: Thu Dec 5 16:26:46 2024 +0100 - upstream: be really strict with fds reserved for communication with the + Skip 2038 key expiry test on 64 bit time_t systems. - separate sshd-session process - reserve them early and fatal if we can't - dup2(2) them later. The pre-split fallback to re-reading the configuration - files is not possible, so sshd-session absolutely requires the fd the - configuration is passed over to be in order. + This allows testing Y2038 with system time set to after that (i.e. 2040), + so that actual Y2038 issues can be exposed, and not masked by key expiry + errors. - ok deraadt@ + Signed-off-by: Alexander Kanavin + +commit 6b4611dc1232c5d2c8e43201f580f19aab320c87 +Author: Darren Tucker +Date: Fri Dec 6 01:45:52 2024 +1100 + + Skip 64bit expiry time test on 32bit time_t. + +commit c9b7866a7dc5e6c30f5aa9d22dd0bbafda0d496f +Author: dtucker@openbsd.org +Date: Thu Dec 5 14:28:39 2024 +0000 + + upstream: Add key expiry test in the 64bit time_t range for additional - OpenBSD-Commit-ID: 308a98ef3c8a6665ebf92c7c9a0fc9600ccd7065 + coverage. From Alexander Kanavin via bz#3684. + + OpenBSD-Regress-ID: bdf6eb3c2421f2e1e11483d03b34c7931d1bccf7 -commit f1c8918cb98459910fb159373baea053ba4108c0 +commit 790c913b5fc6ee93ae14793443dc85a0f574b7eb Author: Damien Miller -Date: Fri May 31 19:12:26 2024 +1000 +Date: Thu Dec 5 19:24:56 2024 +1100 - depend + typo -commit 94b4866cb1f4b0ed29a9f367047b30f81002316f +commit d23a23aaeeabc228792e3fd7eb5f2fa6ae13c482 Author: Damien Miller -Date: Fri May 31 19:11:14 2024 +1000 +Date: Thu Dec 5 08:47:02 2024 +1100 - rename need_privsep to need_chroot + add a Makefile target for ssh-verify-attestation - privsep is mandatory, chroot is optional (disabled when running - sshd as non-root) + Not built by default, but easier than doing it by hand -commit e68a95142e5024b144f8eeccd5ffdee42c34f44c -Author: Damien Miller -Date: Fri May 31 19:05:34 2024 +1000 +commit d0ac63d0f8b5f778d5fd326701ef4489bc27635e +Author: dtucker@openbsd.org +Date: Thu Dec 5 06:49:26 2024 +0000 - remove remaining use_privsep mention + upstream: De-magic the x11 base port number into a define. ok djm@ + + OpenBSD-Commit-ID: 23b85ca9d222cb739b9c33ee5e4d6ac9fdeecbfa -commit b21d271f651d2536dca819cc6d74032fe98634db -Author: djm@openbsd.org -Date: Fri May 31 09:01:08 2024 +0000 +commit 9998c93d57bf0f1df2bc93e0bc2d8112c6f8c720 +Author: dtucker@openbsd.org +Date: Thu Dec 5 06:47:00 2024 +0000 - upstream: warn when -r (deprecated option to disable re-exec) is + upstream: Prevent integer overflow in x11 port handling. These are - passed + theoretically possible if the admin misconfigures X11DisplayOffset or the + user misconfigures their own $DISPLAY, but don't happen in normal operation. + From Suhov Roman via bz#3730, ok djm@ - OpenBSD-Commit-ID: 73145ef5150edbe3ce7889f0844ed8fa6155f551 + OpenBSD-Commit-ID: e9e3860f1a19b862ccf07dc8ecbe8f1e1034f4ed -commit a4b5bc246cbca476deeeb4462aa31746a56e3021 +commit 8c9ee046d40e4254c6c1711783ea11027b72c3e9 Author: djm@openbsd.org -Date: Fri May 31 08:49:35 2024 +0000 +Date: Wed Dec 4 16:42:49 2024 +0000 - upstream: typos + upstream: add a work-in-progress tool to verify FIDO attestation - OpenBSD-Commit-ID: edfa72eb06bfa65da30fabf7d2fe76d2d33f77bf + blobs that ssh-keygen can write when enrolling FIDO keys. + + OpenBSD-Regress-ID: 6c97bf3f46e48866677ad69f54b77683eb92437f -commit 8054b906983ceaed01fabd8188d3dac24c05ba39 -Author: djm@openbsd.org -Date: Mon May 27 01:52:26 2024 +0000 +commit 50c640d874d0246dd0a0d949398c3d7f757c716a +Author: dtucker@openbsd.org +Date: Wed Dec 4 10:51:13 2024 +0000 - upstream: don't need sys/queue.h here + upstream: Don't assume existence of SK provider in test. Patch from - OpenBSD-Commit-ID: dd137396828171eb19e4911581812ca58de6c578 + balu.gajjala at gmail via bz#3402. + + OpenBSD-Regress-ID: d571932016d07d135b54433d07520b9e1901db43 -commit 210d4239733da6180ce853538aeb9413d5c62ad5 -Author: naddy@openbsd.org -Date: Sun May 26 20:35:12 2024 +0000 +commit 73d782693144262570d3585b62f16b183170c014 +Author: djm@openbsd.org +Date: Wed Dec 4 14:37:55 2024 +0000 - upstream: remove references to SSH1 and DSA server keys + upstream: sync the list of options accepted by -o with ssh_config.5 - OpenBSD-Commit-ID: 57cc1c98d4f998981473734f144b904af7d178a2 + prompted by bz3455 + + OpenBSD-Commit-ID: 0ecbfa70aea6c769bcc259defe07182edf461f57 -commit f0b9261d7fdd0ef86806b49fe76344bd16770cd0 -Author: jsg@openbsd.org -Date: Thu May 23 23:47:16 2024 +0000 +commit 6993d9f0959534b0b7d52e17b95e9e79fb0b3d0a +Author: djm@openbsd.org +Date: Wed Dec 4 14:24:20 2024 +0000 - upstream: remove unused struct fwd_perm_list, no decl with complete + upstream: don't screw up ssh-keygen -l output when the file - type ok djm@ + contains CR characters; GHPR236 bz3385, fix from Dmitry Belyavskiy - OpenBSD-Commit-ID: 416fb3970b7e73c76d2963c4f00cf96f2b2ee2fb + OpenBSD-Commit-ID: e458cf6b0adcea5b69ef4c7ba38e590841d02ef4 -commit 2477a98c3ef78e63b11a1393656e00288f52ae97 -Author: naddy@openbsd.org -Date: Wed May 22 15:24:55 2024 +0000 +commit c0b03c2534946fc114880092177aa4a3683ced2d +Author: jsg@openbsd.org +Date: Tue Dec 3 22:30:03 2024 +0000 - upstream: Do not pass -Werror twice when building with clang. + upstream: spelling; ok djm@ - OpenBSD-Commit-ID: 5f378c38ad8976d507786dc4db9283a879ec8cd0 + OpenBSD-Commit-ID: c8ff3f70020451eef214e598117b7ce1a29853ef -commit 435844f5675245b4271f8581f15e6d1f34fde3bc -Author: miod@openbsd.org -Date: Wed May 22 11:49:36 2024 +0000 +commit 97eb247f40167f44324e88a537d5b4fe771a63b2 +Author: dtucker@openbsd.org +Date: Tue Dec 3 16:27:53 2024 +0000 - upstream: Do not pass -Werror if building with gcc 3, for asn1.h + upstream: Remove fallback to compiled-in gropup for dhgex when the - and bio.h cause (admittedly bogus) warnings with gcc 3. + moduli file exists, but does not contain moduli within the client-requested + range. The fallback behaviour remains for the case where the moduli file does + not exist (typically, running tests prior to installing). From bz#2793, based + in part on patch from Joe Testa, ok djm@ - OpenBSD-Commit-ID: fb39324748824cb0387e9d67c41d1bef945c54ea + OpenBSD-Commit-ID: b1a8c5dbbedf249b42474679ebaf14db7332b1ab -commit fc5dc092830de23767c6ef67baa18310a64ee533 -Author: djm@openbsd.org -Date: Wed May 22 04:20:00 2024 +0000 +commit 30c746265ebde29806dba77c92fb1fd3803cbf5c +Author: tb@openbsd.org +Date: Tue Dec 3 15:53:51 2024 +0000 - upstream: this test has been broken since 2014, and has been + upstream: Remove redundant field of definition check - testing the same key exchange algorithm repeatedly instead of testing all of - them. Spotted by nreilly AT blackberry.com in bz3692 + This will allow us to get rid of EC_GROUP_method_of() in the near future. - Who broke the test? me. + ok djm - OpenBSD-Regress-ID: 48f4f5946276f975667141957d25441b3c9a50e2 + OpenBSD-Commit-ID: b4a3d2e00990cf5c2ec6881c21ddca67327c2df8 -commit fd4816791beaed2fdae7eea3e1494d1972b2a39d -Author: anton@openbsd.org -Date: Sun May 19 19:10:01 2024 +0000 +commit eaa1744f34c30740328fd0a0d84b5f2f9e6918c1 +Author: Damien Miller +Date: Thu Dec 5 00:59:19 2024 +1100 - upstream: Add missing kex-names.c source file required since the - - ssh split. + don't ignore changes in regress Makefiles - OpenBSD-Regress-ID: ca666223f828fc4b069cb9016bff1eb50faf9fbb + reported by Torben Hansen in bz2880 -commit beccb7319c5449f6454889013403c336446d622e -Author: naddy@openbsd.org -Date: Fri May 17 14:42:00 2024 +0000 +commit 66e986880b2472fefaad781f10113b138b65ff27 +Author: Damien Miller +Date: Thu Dec 5 00:01:33 2024 +1100 - upstream: remove duplicate copy of relink kit for sshd-session + Support systemd-style socket activation in agent - OpenBSD-Commit-ID: 6d2ded4cd91d4d727c2b26e099b91ea935bed504 - -commit dcd79fa141311c287e0595ede684b7116122fae0 -Author: jsg@openbsd.org -Date: Fri May 17 06:42:04 2024 +0000 - - upstream: remove prototypes with no matching function; ok djm@ + Adds support for systemd LISTEN_PID/LISTEN_FDS socket activation to + ssh-agent. Activated when these environment variables are set and + the agent is started with the -d or -D option and no socket path + is set. - OpenBSD-Commit-ID: 6d9065dadea5f14a01bece0dbfe2fba1be31c693 + Based on GHPR502 by Daniel Kahn Gillmor, ok dtucker -commit 6454a05e7c6574d70adf17efe505a8581a86ca4f -Author: jsg@openbsd.org -Date: Fri May 17 06:38:00 2024 +0000 +commit 9b57c099f57152e6c94f633c114f544087f4bdaa +Author: Darren Tucker +Date: Wed Dec 4 21:36:01 2024 +1100 - upstream: remove externs for removed vars; ok djm@ + Update readme files to better reflect reality. - OpenBSD-Commit-ID: f51ea791d45c15d4927eb4ae7d877ccc1e5a2aab + Prompted by bz#3738, ok djm@. -commit f3e4db4601ef7d2feb1d6f7447e432aaf353a616 -Author: deraadt@openbsd.org -Date: Fri May 17 06:11:17 2024 +0000 +commit ffa885db1b960451d426455045d2f51288e48ee8 +Author: dtucker@openbsd.org +Date: Tue Dec 3 14:12:47 2024 +0000 - upstream: -Werror was turned on (probably just for development), + upstream: Improve description of KbdInteractiveAuthentication. - and this is a simple way to satisfy older gcc. + Based on bz#3658, fixes jmc@ ok markus@ djm@. - OpenBSD-Commit-ID: 7f698df54384b437ce33ab7405f0b86c87019e86 + OpenBSD-Commit-ID: 9fadb56b9afed554d501acbba911c685acd6ffc2 -commit 24a1f3e5ad6f4a49377d4c74c36637e9a239efd0 -Author: Damien Miller -Date: Fri May 17 14:50:43 2024 +1000 +commit b460f82a67795bba37c6cc6c78f788e5b435b4cb +Author: Jonas 'Sortie' Termansen +Date: Sat Nov 2 17:53:23 2024 +0100 - attempt at updating RPM specs for sshd-session + Inherit DESTDIR from the environment. + + autoconf packages conventionally inherit the DESTDIR variable from the + environment. -commit 17b566eeb7a0c6acc9c48b35c08885901186f861 +commit 9da7fa7c7464df241ae5d17da94e4ebed9013719 +Author: Jonas 'Sortie' Termansen +Date: Sat Nov 2 22:10:39 2024 +0100 + + Define u_short and u_long if needed. + +commit d3a7ff7cecbc23cc37044bdf02e7118d05bf3c35 Author: djm@openbsd.org -Date: Fri May 17 04:42:13 2024 +0000 +Date: Tue Dec 3 08:31:49 2024 +0000 - upstream: g/c unused variable + upstream: support FIDO tokens that return no attestation data, e.g. - OpenBSD-Commit-ID: aa6ef0778a1f1bde0d73efba72a777c48d2bd010 + recent WinHello. From Michael Braun via GHPR542 + + OpenBSD-Commit-ID: a71b0542f2f7819ba0e33a88908e01b6fc49e4ce -commit 01fb82eb2aa0a4eaf5c394ea8bb37ea4c26f8a3f -Author: jsg@openbsd.org -Date: Fri May 17 02:39:11 2024 +0000 +commit 96b64056c812620014b65371a9e3ac86bfcd08d5 +Author: Thorsten Kukuk +Date: Tue Nov 19 10:53:28 2024 +0100 - upstream: spelling; ok djm@ + Add wtmpdb support as Y2038 safe wtmp replacement + +commit 1d9563a56f2ad5b0c0aeef20e19c1a03ad54f88a +Author: djm@openbsd.org +Date: Mon Dec 2 14:06:42 2024 +0000 + + upstream: unbreak - OpenBSD-Commit-ID: bdea29bb3ed2a5a7782999c4c663b219d2270483 + OpenBSD-Commit-ID: 05b6c31f4a6e385338f43cc0e08776cea75802a1 -commit b88b690e99145a021fc1a1a116a11e0bce0594e7 +commit d75837b9f6d0d6cc18ed5078789ea0f3dad08f00 Author: djm@openbsd.org -Date: Fri May 17 01:45:22 2024 +0000 +Date: Mon Dec 2 13:37:18 2024 +0000 - upstream: allow overriding the sshd-session binary path + upstream: prefer AES-GCM to AES-CTR; ok deraadt markus - OpenBSD-Regress-ID: 5058cd1c4b6ca1a15474e33546142931d9f964da + OpenBSD-Commit-ID: 8366a72e0f300ee31c5dab2c95025387ec15bbc9 -commit a68f80f2511f0e0c5cef737a8284cc2dfabad818 -Author: anton@openbsd.org -Date: Wed Apr 3 06:01:11 2024 +0000 +commit e19cd494b567a73dc390e09b47c1e21545e6116b +Author: Shiva Kaul +Date: Mon Dec 2 02:04:20 2024 -0500 - upstream: Since ssh-agent(1) is only readable by root by now, use + Fix compilation with DEBUG_SK enabled - ssh(1) while generating data in tests. + In `ssh_ecdsa_sk_verify`, the `datalen` variable was renamed to `dlen` -- but not in this debugging block. + +commit 67ace92be0718df7e0f52c0a76684fc2ebae4089 +Author: dtucker@openbsd.org +Date: Fri Nov 29 00:13:36 2024 +0000 + + upstream: Import regenerated moduli. - OpenBSD-Regress-ID: 24eb40de2e6b0ace185caaba35e2d470331ffe68 + OpenBSD-Commit-ID: 311d271bf0fab8a119e84f4f696d8cd40731692f -commit 92e55890314ce2b0be21a43ebcbc043b4abc232f -Author: djm@openbsd.org -Date: Fri May 17 01:17:40 2024 +0000 +commit ca0697a90e5720ba4d76cb0ae9d5572b5260a16c +Author: Jeremy Stott +Date: Sat Oct 19 12:10:52 2024 +1300 - upstream: fix incorrect debug option name introduce in previous + Add make target for standalone sk-libfido2 - commit + Add a Makefile target for sk-libfido2, the standalone fido2 security + key shared library, suitable for use with the SecurityKeyProvider + option. - OpenBSD-Commit-ID: 66d69e22b1c072c694a7267c847f212284614ed3 + Add a new configure option `--with-security-key-standalone` that + optionally sets the shared library target sk-libfido2$(SHLIBEXT), and + adds it to $(TARGETS). + + misc.h is required when SK_STANDALONE is defined, because of the use + of `monotime_tv` in `sk_select_by_touch`. + + Sets the shared library extension for sk-libfido2 is by setting + `SHLIBEXT` depending on the platform in configure.ac. + + Add the shared library to the CI builds in the `sk` target config to + make sure it can compile under the same conditions as + `--with-security-key-builtin`. + + Add a libssh-pic.a static library that compiles with `-fPIC` reusing + .c.lo method in sk-dummy.so for use in the shared library sk-libfido2. + + Note, a separate static library libssh-pic.a is needed, since defining + -DSK_STANDALONE excludes some symbols needed in sshkey.lo. -commit 4ad72878af7b6ec28da6e230e36a91650ebe84c1 -Author: deraadt@openbsd.org -Date: Fri May 17 00:33:25 2024 +0000 +commit 74d70841efbf41b9fcc8e6f6f4777d2e9d7e2004 +Author: Arnout Engelen +Date: Fri Oct 18 13:42:38 2024 +0200 - upstream: construct and install a relink-kit for sshd-session ok + mdoc2man: balance nested square brackets - djm + I noticed the square brackets in `destination [command [argument...]` + in the synopsis for the `ssh.1` manpage were not balanced, + this balances them. - OpenBSD-Commit-ID: 8b3820adb4da4e139c4b3cffbcc0bde9f08bf0c6 + Signed-off-by: Arnout Engelen -commit 02e679a2cb3f6df8e9dbb1519ed578226485157f -Author: Damien Miller -Date: Fri May 17 12:21:27 2024 +1000 +commit 8eabd2ae2ca1d7756417a1ee5b41f09c5d997634 +Author: djm@openbsd.org +Date: Wed Nov 27 16:07:08 2024 +0000 - Makefile support for sshd-session + upstream: fix argument of "Compression" directive in ssh -G config + + dump, which used to work but broke in 9.8 + + OpenBSD-Commit-ID: c79936242d29c70d01941b28d2d07fd0b85fe46f -commit c0416035c5eaf70a8450d11c8833c5f7068ee7ad +commit 53c03961769d8879a81398074ea3cb36253d4f2e Author: djm@openbsd.org -Date: Fri May 17 00:32:32 2024 +0000 +Date: Wed Nov 27 13:27:34 2024 +0000 - upstream: missing files from previous + upstream: new name/link for agent I-D - OpenBSD-Commit-ID: 4b7be4434d8799f02365552b641a7a70a7ebeb2f + OpenBSD-Commit-ID: e3420f3925a297a1b2ab7dfe7c7d274cfc8e1193 -commit 03e3de416ed7c34faeb692967737be4a7bbe2eb5 +commit 785e3c9110df8f2d30e42ce8b45969c49700f35b Author: djm@openbsd.org -Date: Fri May 17 00:30:23 2024 +0000 +Date: Wed Nov 27 13:00:23 2024 +0000 - upstream: Start the process of splitting sshd into separate - - binaries. This step splits sshd into a listener and a session binary. More - splits are planned. + upstream: mention that biometrics may be used for FIDO key user - After this changes, the listener binary will validate the configuration, - load the hostkeys, listen on port 22 and manage MaxStartups only. All - session handling will be performed by a new sshd-session binary that the - listener fork+execs. + verification as well as PIN. Prompted by Zack Newman, ok jmc@ - This reduces the listener process to the minimum necessary and sets us - up for future work on the sshd-session binary. + OpenBSD-Commit-ID: b774a4438c9be70012661ee278450790d21277b8 + +commit fd2e64c9ec9ea3e89e396be0db41aaf982ae1210 +Author: djm@openbsd.org +Date: Tue Nov 26 22:05:51 2024 +0000 + + upstream: g/c outdated XXX comments - feedback/ok markus@ deraadt@ + OpenBSD-Commit-ID: 74d0c0b74994d9a4343c4d7ea4948cb34f609a6c + +commit 0ad34a6193357d286042322ea7347262a6fb0778 +Author: djm@openbsd.org +Date: Tue Nov 26 22:02:28 2024 +0000 + + upstream: regression test for UpdateHostkeys with multiple keys backed - NB. if you're updating via source, please restart sshd after installing, - otherwise you run the risk of locking yourself out. + by ssh-agent. Patch from Maxime Rey. - OpenBSD-Commit-ID: 43c04a1ab96cdbdeb53d2df0125a6d42c5f19934 + OpenBSD-Regress-ID: 1777ab6e639e57c0e20cbcb6df60455b49fd8bb3 -commit 1c0d81357921f8d3bab06841df649edac515ae5b +commit 84023656d91b78f1ef86c8321ec563f2e90f7227 Author: djm@openbsd.org -Date: Thu May 9 09:46:47 2024 +0000 +Date: Tue Nov 26 22:01:37 2024 +0000 - upstream: simplify exit message handling, which was more complicated + upstream: Explicitly specify the signature algorithm when signing - than it needed to be because of unexpunged ssh1 remnants. ok markus@ + hostkeys-prove requests. - OpenBSD-Commit-ID: 8b0cd2c0dee75fb053718f442aa89510b684610b + Fixes a corner-case triggered by UpdateHostKeys with one or more unknown + host keys stored in ssh-agent where sshd refuses to accept the signature + coming back from the agent. + + Report/fix from Maxime Rey + + OpenBSD-Commit-ID: 460c7d527a24f92b7e5f68ca1a2fa242ebf0d086 -commit cbbbf76aa6cd54fce32eacce1300e7abcf9461d4 -Author: tobias@openbsd.org -Date: Mon May 6 19:26:17 2024 +0000 +commit d1c1cfc5e4e9b43593d4642810ea8135e4c7db49 +Author: djm@openbsd.org +Date: Tue Nov 26 21:23:35 2024 +0000 - upstream: remove SSH1 leftovers + upstream: when using RSA keys to sign messages, select the - Authored with Space Meyer + signature algorithm based on the requested hash algorithm ("-Ohashalg=xxx"). - ok djm + This allows using something other than rsa-sha2-512, which may not + be supported on all signing backends, e.g. some smartcards only + support SHA256. - OpenBSD-Commit-ID: 81db602e4cb407baae472689db1c222ed7b2afa3 + Patch from Morten Linderud; ok markus@ + + OpenBSD-Commit-ID: 246353fac24e92629263996558c6788348363ad7 -commit bc5dcb8ab9a4e8af54a724883732af378f42ea78 -Author: tobias@openbsd.org -Date: Tue Apr 30 15:40:43 2024 +0000 +commit ac7544654441280071b90a4129a47467d40f2389 +Author: djm@openbsd.org +Date: Sun Nov 24 23:47:50 2024 +0000 - upstream: never close stdin - - The sanitise_stdfd call makes sure that standard file descriptors are - open (if they were closed, they are connected with /dev/null). + upstream: turn off CDIAGFLAGS and turn back on INSTALL_STRIP - Do not close stdin in any case to prevent error messages when stdin is - read multiple times and to prevent later usage of fd 0 for connections, - e.g. + accidentally changed in last commit - echo localhost | ssh-keyscan -f - -f - + OpenBSD-Commit-ID: 6d07e4606997e36b860621a14dd41975f2902f8f + +commit 953fa5b59afb04c3c74ed82d7bace65c13cd8baa +Author: Darren Tucker +Date: Sat Nov 9 11:41:44 2024 +1100 + + Disable security key for bigendian interop. - While at it, make stdin-related error messages nicer. + It doesn't currently work. It's not clear why, but I suspect + sk-dummy.so ends up being built for the wrong architecture. + +commit a80eb71c428c474098087c672398f200be8fabdf +Author: Darren Tucker +Date: Sat Nov 9 05:14:16 2024 +1100 + + Reshuffle OpenWRT test configs. - Authored with Max Kunzelmann + Move the the flags used by the OpenWRT distro to mipsel target and + enable OpenSSL on all targets to improve coverage. - ok djm + Explicitly disable security key and openssl on mips target so that host + end of the bigendian interop tests don't attempt them and fail (since + they're not enabled on the target side). + +commit d2709c461359e4129311cdff81ee05242d6c53cd +Author: Darren Tucker +Date: Sat Nov 9 03:26:08 2024 +1100 + + Add keytype to bigendian interop test. + +commit 50ac0f0e0627d29fd9becf5e15e8ceca5ad18078 +Author: Darren Tucker +Date: Sat Nov 9 03:24:29 2024 +1100 + + Ignore chown failure, eg due to dangling symlinks. + +commit 9e528e65a03245cf28e814f09b88c701bec935d1 +Author: Darren Tucker +Date: Sat Nov 2 18:05:41 2024 +1100 + + Test bigendian interop. - OpenBSD-Commit-ID: 48e9b7938e2fa2f9bd47e6de6df66a31e0b375d3 + Where our test target is a bigendian system, do an additional build on + the runner host (which is little endian) and test interop between the two. + Should hopefully catch obvious endianness bugs. -commit 6a42b70e56bef1aacdcdf06352396e837883e84f -Author: Damien Miller -Date: Wed May 8 09:43:59 2024 +1000 +commit dd416f5bfa96ac1ff44b27a93f7b55ee627c6baf +Author: Darren Tucker +Date: Fri Nov 1 19:44:29 2024 +1100 - sync getrrsetbyname.c with recent upstream changes + Allow overridding TEST_SSH_SSHD. + + This will allow tests to specify an alternative sshd, eg on a remote + machine with different endianness. -commit 385ecb31e147dfea59c1c488a1d2011d3867e60e +commit 82662d562cf54829df8a941cdfb2fd307e1d9a90 Author: djm@openbsd.org -Date: Tue Apr 30 06:23:51 2024 +0000 +Date: Wed Nov 6 22:51:26 2024 +0000 - upstream: fix home-directory extension implementation, it always + upstream: ssh-agent implemented an all-or-nothing allow-list of - returned the current user's home directory contrary to the spec. + FIDO application IDs for security key-backed keys, to prevent web key handles + from being used remotely as this would likely lead to unpleasant surprises. + By default, only application IDs that start with "ssh:*" are allowed. - Patch from Jakub Jelen via GHPR477 + This adds a -Owebsafe-allow=... argument that can override the default + list with a more or less restrictive one. The default remains unchanged. - OpenBSD-Commit-ID: 5afd775eab7f9cbe222d7fbae4c793de6c3b3d28 + ok markus@ + + OpenBSD-Commit-ID: 957c1ed92a8d7c87453b9341f70cb3f4e6b23e8d -commit 14e2b16bc67ffcc188906f65008667e22f73d103 -Author: djm@openbsd.org -Date: Tue Apr 30 06:16:55 2024 +0000 +commit 593a0b65c55c1e06a8c22b084aefc395aedb0127 +Author: jca@openbsd.org +Date: Mon Nov 4 21:59:15 2024 +0000 - upstream: flush stdout after writing "sftp>" prompt when not using + upstream: Ignore extra groups that don't fit in the buffer passed - editline. + to getgrouplist(3) - From Alpine Linux via GHPR480 + Our kernel supports 16 groups (NGROUPS_MAX), but nothing prevents + an admin from adding a user to more groups. With that tweak we'll keep + on ignoring them instead of potentially reading past the buffer passed to + getgrouplist(3). That behavior is explicitely described in initgroups(3). - OpenBSD-Commit-ID: 80bdc7ffe0358dc090eb9b93e6dedb2b087b24cd + ok millert@ gilles@ + + OpenBSD-Commit-ID: a959fc45ea3431b36f52eda04faefc58bcde00db -commit 2e69a724051488e3fb3cd11531c4b5bc1764945b +commit e7adebeff3a9d038d0eaeeb0fcefedf29acb7e90 +Author: Damien Miller +Date: Mon Nov 4 14:39:27 2024 +1100 + + Add git signing key for Tim Rice + +commit da4b84845e874f12af7e0686170fa391c919d1df +Author: Darren Tucker +Date: Fri Nov 1 18:51:22 2024 +1100 + + Correct path to c-cpp.yml file in workflow config. + +commit 28740aa2c75392a9c4191eb9523f9b20853e2932 +Author: Darren Tucker +Date: Fri Nov 1 18:44:42 2024 +1100 + + Test new OpenSSL and LibreSSL releases.` + +commit a74809fe06540f16231b354ffe21fcbf39e81f73 +Author: Darren Tucker +Date: Fri Nov 1 18:44:00 2024 +1100 + + Add nbsd10 default test config. + +commit 88b35cbdc1500efece65cd6a9a20a72cf7e46eaa +Author: Damien Miller +Date: Wed Oct 30 14:25:14 2024 +1100 + + fix uint64_t types; reported by Tom G. Christensen + +commit ef7c26cd2f0f9a8222f851d1e551f6dfd3113f8b +Author: Damien Miller +Date: Sun Oct 27 13:28:11 2024 +1100 + + htole64() etc for systems without endian.h + +commit 0c3927c45f8a57b511c874c4d51a8c89414f74ef Author: djm@openbsd.org -Date: Tue Apr 30 05:53:03 2024 +0000 +Date: Sun Oct 27 02:06:59 2024 +0000 - upstream: stricter validation of messaging socket fd number; disallow - - usage of stderr. Based on GHPR492 by RealHurrison + upstream: explicitly include endian.h - OpenBSD-Commit-ID: 73dbbe82ea16f73ce1d044d3232bc869ae2f2ce8 + OpenBSD-Commit-ID: 13511fdef7535bdbc35b644c90090013da43a318 -commit da757b022bf18c6f7d04e685a10cd96ed00f83da +commit cf3e48ee8ba1beeccddd2f203b558fa102be67a2 Author: djm@openbsd.org -Date: Tue Apr 30 05:45:56 2024 +0000 +Date: Sun Oct 27 02:06:01 2024 +0000 - upstream: add missing reserved fields to key constraint protocol + upstream: fix ML-KEM768x25519 KEX on big-endian systems; spotted by - documentation. - - from Wiktor Kwapisiewicz via GHPR487 + jsg@ feedback/ok deraadt@ - OpenBSD-Commit-ID: 0dfb69998cfdb3fa00cbb0e7809e7d2f6126e3df + OpenBSD-Commit-ID: 26d81a430811672bc762687166986cad40d28cc0 -commit 16d0b82fa08038f35f1b3630c70116979f49784f -Author: Damien Miller -Date: Tue Apr 30 12:39:34 2024 +1000 +commit ae566d51b64fa3dce7063e7745b9b35f8f47abde +Author: naddy@openbsd.org +Date: Fri Oct 25 21:53:24 2024 +0000 - depend + upstream: mlkem768x25519-sha256 has been promoted to default key + + exchange + + OpenBSD-Commit-ID: 5a3259a193fd42108a869ebf650b95b5f2d08dcf -commit 66aaa678dbe59aa21d0d9d89a3596ecedde0254b -Author: djm@openbsd.org -Date: Tue Apr 30 02:14:10 2024 +0000 +commit 3af1dba1384ca896df6e973c70398c41d36de1ea +Author: Darren Tucker +Date: Fri Oct 25 19:04:30 2024 +1100 - upstream: correctly restore sigprocmask around ppoll() reported + Retire the minix3 test config. - by Tõivo Leedjärv; ok deraadt@ + It got broken by the sshd-auth change, it's not obvious why, and the + platform lacks the debugging tools (eg gdb, strace) to figure it out. + The upstream project seems effectively dead (6 years since the last + commit, 10 since the last release). It was useful while it lasted + (we found a real bug because of it) but its time seems to have passed. + +commit 3b240cc44b8de9175280ddbe59331317d427b0e3 +Author: Preetish Amballi +Date: Mon Oct 21 14:07:02 2024 +0000 + + Updated gitignore to ignore sshd-session and sshd-auth targets + +commit 326495744f06a0ab18ee0d16f87b3fe91cac92fb +Author: Darren Tucker +Date: Fri Oct 25 19:01:02 2024 +1100 + + Simplify pselect shim and remove side effects. - OpenBSD-Commit-ID: c0c0f89de5294a166578f071eade2501929c4686 + Instead of maintaing state (pipe descriptors, signal handlers) across + pselect-on-select invocations, set up and restore them each call. + This prevents outside factors (eg a closefrom or signal handler + installation) from potentially causing problems. This does result in a + drop in throughput of a couple of percent on geriatric platforms without + a native pselect due to the extra overhead. Tweaks & ok djm@ -commit 80fb0eb21551aed3aebb009ab20aeffeb01e44e0 +commit e53b615f3934ffac1efb3c1e491d126b9b09fd24 Author: djm@openbsd.org -Date: Tue Apr 30 02:10:49 2024 +0000 +Date: Fri Oct 25 01:34:18 2024 +0000 - upstream: add explict check for server hostkey type against + upstream: promote mlkem768x25519-sha256 to be the default key exchange; - HostkeyAlgorithms. Allows HostkeyAlgorithms to disable implicit fallback from - certificate keys to plain keys. ok markus@ + ok markus@ - OpenBSD-Commit-ID: 364087e4a395ff9b2f42bf3aefdb2090bb23643a + OpenBSD-Commit-ID: fc673065e6505bb06b2e2b9362f78ccb4200a828 -commit 5b28096d31ff7d80748fc845553a4aef5bb05d86 -Author: jsg@openbsd.org -Date: Tue Apr 23 13:34:50 2024 +0000 +commit de644b1831b970f6655f871c051774cc871e8e74 +Author: djm@openbsd.org +Date: Thu Oct 24 03:28:34 2024 +0000 - upstream: correct indentation; no functional change ok tb@ + upstream: test SIGUSR1 dropping all keys from ssh-agent - OpenBSD-Commit-ID: dd9702fd43de546bc6a3f4f025c74d6f3692a0d4 + OpenBSD-Regress-ID: 8654b9aa8eb695b1499fffc408c25319592bf0e0 -commit fd3cb8a82784e05f621dea5b56ac6f89bc53c067 -Author: semarie@openbsd.org -Date: Thu Apr 4 16:00:51 2024 +0000 +commit e86d7a077ce9a2b9ee9d4138c358a17cbdb786f9 +Author: djm@openbsd.org +Date: Thu Oct 24 03:15:47 2024 +0000 - upstream: set right mode on ssh-agent at boot-time + upstream: amake ssh-agent drop all keys when it receives SIGUSR1; + + let's users zap keys without access to $SSH_AUTH_SOCK - which sthen@ ok deraadt@ - OpenBSD-Commit-ID: 662b5056a2c6171563e1626f9c69f27862b5e7af + OpenBSD-Commit-ID: dae9db0516b1011e5ba8c655ac702fce42e6c023 -commit 54343a260e3aa4bceca1852dde31cd08e2abd82b -Author: deraadt@openbsd.org -Date: Tue Apr 2 12:22:38 2024 +0000 +commit 94cdfebec852a2429c008cc2a55f8e4183f36972 +Author: djm@openbsd.org +Date: Thu Oct 24 03:14:37 2024 +0000 - upstream: Oops, incorrect hex conversion spotted by claudio. + upstream: relax valid_domain() checks to allow an underscore as the - While here try to improve how it reads a bit better. Surprising the - regression tests didn't spot this error, maybe it fails to roundtrip the - values. + first character. ok deraadt@ - OpenBSD-Commit-ID: 866cfcc1955aef8f3fc32da0b70c353a1b859f2e + OpenBSD-Commit-ID: 3f8be6d32496e5596dd8b14e19cb067ddd7969ef -commit ec78c31409590ad74efc194f886273ed080a545a -Author: deraadt@openbsd.org -Date: Tue Apr 2 10:02:08 2024 +0000 +commit 1b05d5437bf45bee5e3104772dea06ed51764f1b +Author: dtucker@openbsd.org +Date: Tue Oct 22 07:13:28 2024 +0000 - upstream: for parse_ipqos(), use strtonum() instead of mostly + upstream: Remove sshd logfile in start_sshd - idiomatic strtoul(), but wow it's so gross. ok djm + ... and ssh and sshd log wrappers before recreating them. Prevents "can't + create" errors during tests when running tests without SUDO after having + run them with SUDO. - OpenBSD-Commit-ID: cec14a76af2eb7b225300c80fc0e21052be67b05 + OpenBSD-Regress-ID: 2f0a83532e3dccd673a9bf0291090277268c69a6 -commit 8176e1a6c2e6da9361a7abb6fbf6c23c299f495b -Author: deraadt@openbsd.org -Date: Tue Apr 2 09:56:58 2024 +0000 +commit 307ab3c7720f8879b835614b02687358ee4df9b9 +Author: dtucker@openbsd.org +Date: Tue Oct 22 06:16:26 2024 +0000 - upstream: can shortcut by returning strtonum() value directly; ok + upstream: Add a sshd debug wrapper - djm + ... to run all of the subprograms from the build directory while + developing and debugging. Should help prevent accidentally testing + against unchanged installed sshd-auth and sshd-session binaries. ok djm@ - OpenBSD-Commit-ID: 7bb2dd3d6d1f288dac14247d1de446e3d7ba8b8e + OpenBSD-Commit-ID: 61760cdc98c2bc8f1e9f83a6f97cca0f66b52e69 -commit 9f543d7022a781f80bb696f9d73f1d1c6f9e31d6 -Author: deraadt@openbsd.org -Date: Tue Apr 2 09:52:14 2024 +0000 +commit 87bd1cb3ccba5e91d2650eb7f753c898ee43858e +Author: dtucker@openbsd.org +Date: Tue Oct 22 06:13:00 2024 +0000 - upstream: rewrite convtime() to use a isdigit-scanner and + upstream: Make debug call printf("%s", NULL) safe. - strtonum() instead of strange strtoul can might be fooled by garage - characters. passes regress/usr.bin/ssh/unittests/misc ok djm + Prevents problems on platforms where this isn't safe (which it's not + required to be). ok djm@ - OpenBSD-Commit-ID: 4b1ef826bb16047aea3f3bdcb385b72ffd450abc + OpenBSD-Commit-ID: 8fa4ce3ad90915c925b81b99a79ab920b0523387 -commit 8673137f780d8d9e4cda3c4605cb5d88d5cea271 -Author: claudio@openbsd.org -Date: Tue Apr 2 09:48:24 2024 +0000 +commit c44c349edd157b2c00c42bd5ef5f9dfb37de26f3 +Author: Darren Tucker +Date: Tue Oct 22 17:48:32 2024 +1100 - upstream: Remove unused ptr[3] char array in pkcs11_decode_hex. + Resync cvsid missed in commit 6072e4c9. + +commit fe4305c37ffe53540a67586854e25f05cf615849 +Author: djm@openbsd.org +Date: Fri Oct 18 05:53:26 2024 +0000 + + upstream: mention that LocalForward and RemoteForward can accept Unix - OK deraadt@ + domain socket paths; GHPR115 - OpenBSD-Commit-ID: 3d14433e39fd558f662d3b0431c4c555ef920481 + OpenBSD-Commit-ID: a8a34d0a0c51a9ddab3dfce615f9878fa76ef842 -commit c7fec708f331f108343d69e4d74c9a5d86d6cfe7 -Author: deraadt@openbsd.org -Date: Tue Apr 2 09:32:28 2024 +0000 +commit 9c97b6af8e052ab5ffe0f9096fadc8f9a4d0ed0f +Author: djm@openbsd.org +Date: Fri Oct 18 05:45:40 2024 +0000 - upstream: Replace non-idiomatic strtoul(, 16) to parse a region + upstream: remove duplicate check; GHPR392 from Pedro Martelletto - of 2-character hex sequences with a low-level replacement designed just for - the task. ok djm + OpenBSD-Commit-ID: 597ab7dd3f0e78939d2659fc1904d0f39ee95487 + +commit d9cd208e89a471a3ff8adfcec68d6210af9e9fd5 +Author: djm@openbsd.org +Date: Fri Oct 18 05:37:24 2024 +0000 + + upstream: allow "-" as output file for moduli screening - OpenBSD-Commit-ID: 67bab8b8a4329a19a0add5085eacd6f4cc215e85 + based on GHPR393 + + OpenBSD-Commit-ID: 1517763764eb55d03a6092dd120d2909c6fef0e1 -commit 019a5f483b0f588da6270ec401d0b4bb35032f3f -Author: deraadt@openbsd.org -Date: Tue Apr 2 09:29:31 2024 +0000 +commit 5eb5c4b2820d0636b1eccee646fb32ec946c4a95 +Author: djm@openbsd.org +Date: Fri Oct 18 05:32:51 2024 +0000 - upstream: Use strtonum() instead of severely non-idomatic + upstream: ssh-keyscan doesn't need it's own sshfatal() definition, it - strtoul() In particular this will now reject trailing garbage, ie. - '12garbage'. ok djm + can use the shared one from fatal.c - OpenBSD-Commit-ID: c82d95e3ccbfedfc91a8041c2f8bf0cf987d1501 + based on GHPR401 from lengyijun + + OpenBSD-Commit-ID: 8ea75ea99f27f464c9223cbc89cb046ccf9cd5c4 -commit 8231ca046fa39ea4eb99b79e0a6e09dec50ac952 -Author: deraadt@openbsd.org -Date: Mon Apr 1 15:50:17 2024 +0000 +commit 0a1e75499e2c6fc258ee903645c878480949f362 +Author: djm@openbsd.org +Date: Fri Oct 18 05:14:51 2024 +0000 - upstream: also create a relink kit for ssh-agent, since it is a + upstream: in _ssh_order_hostkeyalgs() consider ECDSA curve type when - long-running setgid program carrying keys with some (not very powerful) - communication channels. solution for testing the binary from dtucker. - agreement from djm. Will add it into /etc/rc in a few days. + arranging the hostkey algorithms. AFAIK this code is unused in OpenSSH, but I + guess others are using it - OpenBSD-Commit-ID: 2fe8d707ae35ba23c7916adcb818bb5b66837ba0 + based on GHPR387 from Pawel Jakub Dawidek + + OpenBSD-Commit-ID: 4d462495ac0c40f7b7dd66178e0005b9b2128225 -commit bf7bf50bd6a14e49c9c243cb8f4de31e555a5a2e -Author: deraadt@openbsd.org -Date: Mon Apr 1 15:48:16 2024 +0000 +commit d01ee7a88c5f4b1aa8c75a7c739f8f3bc1ad8bde +Author: djm@openbsd.org +Date: Fri Oct 18 05:03:34 2024 +0000 - upstream: new-style relink kit for sshd. The old scheme created + upstream: require control-escape character sequences passed via the '-e - a Makefile by concatenating two Makefiles and was incredibly fragile. In the - new way a narrow-purposed install.sh script is created and shipped with the - objects. A recently commited /etc/rc script understands these files. + ^x' commandline to be exactly two characters long. Avoids one by OOB read if + ssh is invoked as "ssh -e^ ..." - OpenBSD-Commit-ID: ef9341d5a50f0d33e3a6fbe995e92964bc7ef2d3 + Spotted by Maciej Domanski in GHPR368 + + OpenBSD-Commit-ID: baa72bc60898fc5639e6c62de7493a202c95823d -commit 00e63688920905e326d8667cb47f17a156b6dc8f -Author: renmingshuai -Date: Fri Apr 12 10:20:49 2024 +0800 +commit 74ff6382f5743e09930e6cbd195dac65cd6062c9 +Author: djm@openbsd.org +Date: Fri Oct 18 04:30:09 2024 +0000 - Shell syntax fix (leftover from a sync). + upstream: remove addr.[ch] functions that are unused and - Signed-off-by: renmingshuai + visbility-restrict ones that are unused outside the implementation itself; + based on GHPR#282 by tobias@ + + OpenBSD-Commit-ID: a0140f2418b4d46cfaa7b33febc0a0931f9b2744 -commit 2eded551ba96e66bc3afbbcc883812c2eac02bd7 -Author: Darren Tucker -Date: Thu Apr 25 13:20:19 2024 +1000 +commit a9d6d7d93c533fa729f08b405e786d912553f33e +Author: djm@openbsd.org +Date: Fri Oct 18 04:14:59 2024 +0000 - Merge flags for OpenSSL 3.x versions. + upstream: unreachable POLLERR case; from ya0guang via GHPR485 - OpenSSL has moved to 3.4 which we don't currently accept. Based on - the OpenSSL versioning policy[0] it looks like all of the 3.x versions - should work with OpenSSH, so remove the distinction in configure and - accept all of them. + OpenBSD-Commit-ID: b3c82655190532b01eb817e532742cfaa4687eff + +commit d76424bf279ff951383e21213eb3759ea4090674 +Author: djm@openbsd.org +Date: Fri Oct 18 04:11:54 2024 +0000 + + upstream: s/Sx/Cm/ for external references; from Domen Puncer - [0] https://openssl.org/policies/general/versioning-policy.html + Kugler via GHPR501 + + OpenBSD-Commit-ID: f864a34feb5d5ff17160cf7c42ad0f7744fe8a3f -commit 8673245918081c6d1dc7fb3733c8eb2c5a902c5e +commit ca204b994e2981e7bf95627b3105408917105649 +Author: naddy@openbsd.org +Date: Mon Oct 14 23:53:34 2024 +0000 + + upstream: mention SshdAuthPath option; ok djm@ + + OpenBSD-Commit-ID: 9a5d3add25e4e77bd3805bc5583a842ecf34d85c + +commit be27770e840c4dd9d9fcad1aa879400c727d7c2f Author: Darren Tucker -Date: Thu Apr 25 13:19:03 2024 +1000 +Date: Fri Oct 18 13:37:55 2024 +1100 - Remove 9.6 branch from status page. + Remove references to systrace and pledge sandboxes. + + ok djm@ -commit 70d43049747fa3c66cf876d52271859407cec2fa +commit 49e64bf63fbf2f14961062dafe8ef08cb816bb08 +Author: Pavel Miadzvedzeu +Date: Wed Apr 24 10:19:56 2024 +0300 + + Fix "undeclared 'ut'" error by replacing it with 'utx' + +commit 67f684733f60f66479854a2867b953de731e71b2 Author: Darren Tucker -Date: Thu Apr 25 13:16:58 2024 +1000 +Date: Thu Oct 17 20:50:29 2024 +1100 - Update LibreSSL and OpenSSL versions tested. + Seed RNG when starting up sshd-auth. - Update LibreSSL versions to current releases (3.8.4 & 3.9.1). - Add newly-released OpenSSL 3.3.0, and add tests against the 3.1 and - 3.3 branches. + Makes builds configured --without-openssl work again since otherwise + the first use of the RNG comes after the sandbox init and it can't + open /dev/random. -commit 88351eca17dcc55189991ba60e50819b6d4193c1 -Author: 90 -Date: Fri Apr 5 19:36:06 2024 +0100 +commit c06c681aeebbe8e84e7410095514e7ee91f7e6cb +Author: Darren Tucker +Date: Thu Oct 17 19:18:23 2024 +1100 - Fix missing header for systemd notification + MacOS 12 runners are deprecated, replace with 15. -commit 08f579231cd38a1c657aaa6ddeb8ab57a1fd4f5c +commit 39db1f23bafb48a7c0cc9c65c716a0370f4cc677 Author: Damien Miller -Date: Wed Apr 3 14:40:32 2024 +1100 +Date: Thu Oct 17 13:28:47 2024 +1100 - notify systemd on listen and reload + Fix lookup path for sshd-auth; bz3745 + +commit c537eeb1ae5f069450053b0027e64efe5bdb37d2 +Author: Damien Miller +Date: Wed Oct 16 08:28:21 2024 +1100 + + fix breakage; missing saved_argc symbol + +commit 98a0883bdef28a06c7e017f27adf21ba57898bf4 +Author: Damien Miller +Date: Mon Oct 14 17:17:50 2024 +1100 + + fix capsicum sandbox + +commit 164ea4380564a2a83713eacf71908e3946e5e4e4 +Author: Damien Miller +Date: Mon Oct 14 17:16:41 2024 +1100 + + put back some portable bits for sshd-auth.c + +commit f8edf08c258ee2918689872c4702302052729726 +Author: Damien Miller +Date: Mon Oct 14 14:49:25 2024 +1100 + + there's only one sandbox, move to a static global + +commit 4482f0042b41d3d63c3845d7ba9fcf47c9252a84 +Author: Damien Miller +Date: Mon Oct 14 14:49:20 2024 +1100 + + depend + +commit 74856204a353a187dc6e7706c6cf84b7f14d775d +Author: djm@openbsd.org +Date: Mon Oct 14 03:02:08 2024 +0000 + + upstream: regress support for split sshd-auth binary - Standalone implementation that does not depend on libsystemd. - With assistance from Luca Boccassi, and feedback/testing from Colin - Watson. bz2641 + OpenBSD-Regress-ID: df7d18a87b475f70004770f0f4e404adba5f6ab7 -commit 43e7c1c07cf6aae7f4394ca8ae91a3efc46514e2 -Author: Darren Tucker -Date: Sun Mar 31 21:51:57 2024 +1100 +commit 461741083d7254595fecea274e60fe3ebf3ce3f9 +Author: djm@openbsd.org +Date: Fri Sep 27 01:05:54 2024 +0000 - Port changes from selfhosted to upstream tests. + upstream: test some more Match syntax, including criteria=arg and - Should get them working again. + negations + + OpenBSD-Regress-ID: 67476baccc60bf1a255fd4e329ada950047b8b8d -commit 281ea25a44bff53eefb4af7bab7aa670b1f8b6b2 -Author: Darren Tucker -Date: Sat Mar 30 18:20:16 2024 +1100 +commit 6072e4c9385713e9c166f32cfca6a7e603d4f0b8 +Author: djm@openbsd.org +Date: Mon Oct 14 01:57:50 2024 +0000 - Check if OpenSSL implementation supports DSA. + upstream: Split per-connection sshd-session binary - If --enable/disable-dsa-keys is not specified, set based on what OpenSSL - supports. If specified as enabled, but not supported by OpenSSL error - out. ok djm@ + This splits the user authentication code from the sshd-session + binary into a separate sshd-auth binary. This will be executed by + sshd-session to complete the user authentication phase of the + protocol only. + + Splitting this code into a separate binary ensures that the crucial + pre-authentication attack surface has an entirely disjoint address + space from the code used for the rest of the connection. It also + yields a small runtime memory saving as the authentication code will + be unloaded after thhe authentication phase completes. + + Joint work with markus@ feedback deraadt@ + + Tested in snaps since last week + + OpenBSD-Commit-ID: 9c3b2087ae08626ec31b4177b023db600e986d9c -commit 2d2c068de8d696fe3246f390b146197f51ea1e83 +commit fe6c6330c1a94c7a537efe9069853ce7a275c50a Author: djm@openbsd.org -Date: Sat Mar 30 05:56:22 2024 +0000 +Date: Sun Oct 13 22:20:06 2024 +0000 - upstream: in OpenSSH private key format, correct type for subsequent + upstream: don't start the ObscureKeystrokeTiming mitigations if - private keys in blob. From Jakub Jelen via GHPR430 + there has been traffic on a X11 forwarding channel recently. - OpenBSD-Commit-ID: d17dbf47554de2d752061592f95b5d772baab50b + Should fix X11 forwarding performance problems when this setting is + enabled. Patch from Antonio Larrosa via bz3655 + + OpenBSD-Commit-ID: 820284a92eb4592fcd3d181a62c1b86b08a4a7ab -commit c2c0bdd3e96b3ef66d77fccb85ff4962dc76caf0 -Author: Eero Häkkinen -Date: Sat Sep 16 00:55:08 2023 +0300 +commit 538cd28598ae942c94b99855b06fdd937e2e7381 +Author: jsg@openbsd.org +Date: Sat Oct 12 10:50:37 2024 +0000 - Expose SSH_AUTH_INFO_0 always to PAM auth modules. + upstream: remove duplicate misc.h include ok dtucker@ - This changes SSH_AUTH_INFO_0 to be exposed to PAM auth modules also - when a password authentication method is in use and not only - when a keyboard-interactive authentication method is in use. + OpenBSD-Commit-ID: fdd056e7854294834d54632b4282b877cfe4c12e -commit 02c5ad23124ae801cf248d99ea5068fc4331ca01 -Author: Darren Tucker -Date: Wed Mar 27 17:42:58 2024 +1100 +commit 0051381a8c33740a77a1eca6859efa1c78887d80 +Author: djm@openbsd.org +Date: Sun Oct 6 23:37:17 2024 +0000 - Rearrange selfhosted VM scheduling. + upstream: Turn off finite field (a.k.a modp) Diffie-Hellman key - Instead of trying to infer the type of the self hosted tests in each of - the driver scripts (inconsistently...), set one of the following - variables to "true" in the workflow: + exchange in sshd by default. Specifically, this removes the + diffie-hellman-group* and diffie-hellman-group-exchange-* methods. The client + is unchanged and continues to support these methods by default. - VM: tests run in a virtual machine. - EPHEMERAL: tests run on an ephemeral virtual machine. - PERSISTENT: tests run on a persistent virtual machine - REMOTE: tests run on a physical remote host. + Finite field Diffie Hellman is slow and computationally expensive for + the same security level as Elliptic Curve DH or PQ key agreement while + offering no redeeming advantages. - EPHEMERAL VMs can have multiple instances of any given VM can exist - simultaneously and are run by a runner pool. The other types have a - dedicated runner instance and can only run a single test at a time. + ECDH has been specified for the SSH protocol for 15 years and some + form of ECDH has been the default key exchange in OpenSSH for the last + 14 years. - Other settings: - SSHFS: We need to sshfs mount over the repo so the workflow can collect - build artifacts. This also implies the tests must be run over ssh. - DEBUG_ACTIONS: enable "set -x" in scripts for debugging. + ok markus@ + + OpenBSD-Commit-ID: 4e238ad480a33312667cc10ae0eb6393abaec8da -commit cd8a72707c02615365d0851ac51063ab6bfe258f -Author: Damien Miller -Date: Sat Mar 30 16:05:59 2024 +1100 +commit 67a115e7a56dbdc3f5a58c64b29231151f3670f5 +Author: djm@openbsd.org +Date: Thu Sep 26 23:55:08 2024 +0000 - add new token-based signing key for dtucker@ + upstream: fix previous change to ssh_config Match, which broken on - Verified in person and via signature with old key. - Will remove old key in a bit. + negated Matches; spotted by phessler@ ok deraadt@ + + OpenBSD-Commit-ID: b1c6acec66cd5bd1252feff1d02ad7129ced37c7 -commit 8d0e46c1ddb5b7f0992591b0dc5d8aaa77cc9dba -Author: Alkaid -Date: Tue Mar 12 03:59:12 2024 -0700 +commit 220b6c1290042acd5180d783dea01efe1365c265 +Author: jsg@openbsd.org +Date: Wed Sep 25 23:01:39 2024 +0000 - Fix OpenSSL ED25519 support detection + upstream: remove some unused defines; ok djm@ - Wrong function signature in configure.ac prevents openssh from enabling - the recently new support for ED25519 priv keys in PEM PKCS8 format. + OpenBSD-Commit-ID: 3a63e4e11d455704f684c28715d61b17f91e0996 -commit 697359be9c23ee43618243cdbcc9c7981e766752 -Author: djm@openbsd.org -Date: Sat Mar 30 04:27:44 2024 +0000 +commit 3ef4f6e8a4d774f73852391fdccbb95f39fc71bf +Author: jmc@openbsd.org +Date: Wed Sep 25 06:13:01 2024 +0000 - upstream: allow WAYLAND_DISPLAY to enable SSH_ASKPASS + upstream: remove some unneeded Xo/Xc calls; from evan silberman the - From dkg via GHPR479; ok dtucker@ + original diff had a couple of errors, which i've fixed - OpenBSD-Commit-ID: 1ac1f9c45da44eabbae89375393c662349239257 + OpenBSD-Commit-ID: f37ad5888adbc0d4e1cd6b6de237841f4b1e650d -commit 7844705b0364574cc70b941be72036c2c2966363 -Author: dtucker@openbsd.org -Date: Fri Mar 29 10:40:07 2024 +0000 +commit 3f02368e8e9121847727c46b280efc280e5eb615 +Author: djm@openbsd.org +Date: Wed Sep 25 01:24:04 2024 +0000 - upstream: Use egrep instead of grep -E. + upstream: fix regression introduced when I switched the "Match" - Some plaforms don't have the latter so this makes things easier - in -portable. + criteria tokeniser to a more shell-like one. Apparently the old tokeniser + (accidentally?) allowed "Match criteria=argument" as well as the "Match + criteria argument" syntax that we tested for. - OpenBSD-Regress-ID: ff82260eb0db1f11130200b25d820cf73753bbe3 + People were using this syntax so this adds back support for + "Match criteria=argument" + + bz3739 ok dtucker + + OpenBSD-Commit-ID: d1eebedb8c902002b75b75debfe1eeea1801f58a -commit 22b2b6c555334bffdf357a2e4aa74308b03b83c3 -Author: dtucker@openbsd.org -Date: Tue Mar 26 08:09:16 2024 +0000 +commit 9517cc58577f85a0ba5f8bb46778dff625f0688f +Author: djm@openbsd.org +Date: Tue Sep 24 02:28:17 2024 +0000 - upstream: test -h is the POSIXly way of testing for a symlink. Reduces + upstream: some extra paranoia, reminded by jsg@ - diff vs Portable. + OpenBSD-Commit-ID: 22072bfa1df1391858ae7768a6c627e08593a91e + +commit 815a94e86a68c1000b8310cb47695cea9329516c +Author: Damien Miller +Date: Wed Sep 25 11:15:45 2024 +1000 + + gss-serv.c needs sys/param.h - OpenBSD-Regress-ID: 6f31cd6e231e3b8c5c2ca0307573ccb7484bff7d + From Void Linux -commit edcff77f82c2bb2b5653b36f1e47274c5ef3e8be -Author: Darren Tucker -Date: Tue Mar 26 18:58:58 2024 +1100 +commit 76a618d2842c34c16cd21a4efc7230e2f459008d +Author: Damien Miller +Date: Wed Sep 25 11:13:05 2024 +1000 - Fix name of OpenBSD upstream CI jobs. + build construct_utmp() when USE_BTMP is set + + Fixes compile error on Void Linux/Musl -commit 861b084429940e024f1b6e9c2779eac95d7a45db +commit d3aee17f6d395202eaa42a0c449b6da41f61527c Author: Darren Tucker -Date: Tue Mar 26 18:55:33 2024 +1100 +Date: Tue Sep 24 18:41:44 2024 +1000 - Resync with upstream: ${} around DATAFILE. + Test the flags from OpenWRT's package. -commit 63f248c7693e7f0a3b9a13d2980ac9a7e37f2aea -Author: djm@openbsd.org -Date: Mon Mar 25 19:28:09 2024 +0000 +commit 0f5d19e6fe4b58a89e6dc8c71a2aae30365d193e +Author: Christoph Ostarek +Date: Wed Jul 3 12:46:59 2024 +0200 - upstream: optional debugging + fix utmpx ifdef - OpenBSD-Regress-ID: b4852bf97ac8fb2e3530f2d5f999edd66058d7bc + 02e16ad95fb1f56ab004b01a10aab89f7103c55d did a copy-paste for + utmpx, but forgot to change the ifdef appropriately -commit 16e2ebe06a62f09d4877b769876d92d6008a896f -Author: dtucker@openbsd.org -Date: Mon Mar 25 06:05:42 2024 +0000 +commit e03239f999acf9dc3da0f2f72bde36abbe678911 +Author: jsg@openbsd.org +Date: Sun Sep 22 12:56:21 2024 +0000 - upstream: Verify string returned from local shell command. + upstream: remove some unused defines; ok djm@ - OpenBSD-Regress-ID: 5039bde24d33d809aebfa8d3ad7fe9053224e6f8 + OpenBSD-Commit-ID: 81869ee6356fdbff19dae6ff757095e6b24de712 -commit b326f7a1f39ff31324cc3fe2735178fb474c04a4 -Author: dtucker@openbsd.org -Date: Mon Mar 25 03:30:31 2024 +0000 +commit a35f543d3a6275fef781e515c262d1c687c3bc28 +Author: jsg@openbsd.org +Date: Fri Sep 20 02:00:46 2024 +0000 - upstream: Improve shell portability: grep -q is not portable so - - redirect stdout, and use printf instead of relying on echo to do \n - substitution. Reduces diff vs Portable. - - Also resync somewhat with upstream. + upstream: remove unneeded semicolons; checked by millert@ - OpenBSD-Regress-ID: 9ae876a8ec4c4725f1e9820a0667360ee2398337 + OpenBSD-Commit-ID: 3fb621a58e04b759a875ad6a33f35bb57ca80231 -commit dbf2e319f0c582613fa45a735ea3c242ce56946b -Author: dtucker@openbsd.org -Date: Mon Mar 25 02:07:08 2024 +0000 +commit 1641f2d4d6e05d2147913442864cae546e64f08b +Author: Darren Tucker +Date: Mon Sep 23 20:52:31 2024 +1000 - upstream: Save error code from SSH for use inside case statement, - - from portable. In some shells, "case" will reset the value of $?, so save it - first. - - OpenBSD-Regress-ID: da32e5be19299cb4f0f7de7f29c11257a62d6949 + Add 9.9 branch to CI status console. -commit d2c8c4fa7def4fb057ed05b3db57b62c810a26f6 -Author: dtucker@openbsd.org -Date: Mon Mar 25 01:40:47 2024 +0000 +commit 46d1fb16b20e971b9ac15e86a3d3e350b49c9ad6 +Author: Damien Miller +Date: Fri Sep 20 08:20:13 2024 +1000 - upstream: Increase timeout. Resyncs with portable where some of - - the test VMs are slow enough for this to matter. - - OpenBSD-Regress-ID: 6a83a693602eb0312f06a4ad2cd6f40d99d24b26 + update version numbers -commit 83621b63514a84791623db3efb59d38bc4bf9563 -Author: dtucker@openbsd.org -Date: Mon Mar 25 01:28:29 2024 +0000 +commit 0bdca1f218971b38728a0a129f482476baff0968 +Author: djm@openbsd.org +Date: Thu Sep 19 22:17:44 2024 +0000 - upstream: In PuTTY interop test, don't assume the PuTTY major - - version is 0. Patch from cjwatson at debian.org via bz#3671. + upstream: openssh-9.9 - OpenBSD-Regress-ID: 835ed03c1b04ad46be82e674495521f11b840191 - -commit 8a421b927700f3834b4d985778e252b8e3299f83 -Author: Darren Tucker -Date: Tue Mar 26 18:38:14 2024 +1100 - - Really mkdir /usr/local/etc in CI tests. - -commit 2946ed522c47ce045314533d426b4e379f745e59 -Author: Darren Tucker -Date: Tue Mar 26 17:19:09 2024 +1100 - - Better short name for OpenBSD upstream CI jobs too. - -commit 18dbe8eff647aacb82d7e86b4ce63d5beee11f25 -Author: Darren Tucker -Date: Tue Mar 26 17:13:52 2024 +1100 + OpenBSD-Commit-ID: 303417285f1a73b9cb7a2ae78d3f493bbbe31f98 - Ensure /usr/local/etc exists before using in tests. - -commit 5fc1085128e3348bb1b5ee4d955cc767b019b3ad -Author: Darren Tucker -Date: Tue Mar 26 16:50:46 2024 +1100 +commit ef2d7f2d3e1b4c9ae71bacf963e76a92ab8be543 +Author: Damien Miller +Date: Wed Sep 18 16:03:23 2024 +1000 - Be more specific about when to rerun workflows. + include openbsd-compat/base64.c license in LICENSE -commit 5516923e8ae3da0823fea0d7d28aa813627142c0 -Author: Darren Tucker -Date: Tue Mar 26 16:35:27 2024 +1100 +commit 7ef362b989c8d1f7596f557f22e5924b9c08f0ea +Author: Damien Miller +Date: Wed Sep 18 09:01:23 2024 +1000 - Add short names for test jobs on github CI. + conditionally include mman.h in arc4random code -commit dc37d2d2470b4a9cedcee9ac926b7362214e3305 -Author: Darren Tucker -Date: Tue Mar 26 16:26:14 2024 +1100 +commit 5fb2b5ad0e748732a27fd8cc16a7ca3c21770806 +Author: Damien Miller +Date: Tue Sep 17 11:53:24 2024 +1000 - If we're using xpg4's id, remember to pass args. + fix bug in recently-added sntrup761 fuzzer + + key values need to be static to persist across invocations; + spotted by the Qualys Security Advisory team. -commit fe169487937780392b23d3ff3c00e5898c10f784 -Author: dtucker@openbsd.org -Date: Tue Mar 26 01:23:11 2024 +0000 +commit 0ca128c9ee894f1b0067abd473bfb33171df67f8 +Author: djm@openbsd.org +Date: Mon Sep 16 05:37:05 2024 +0000 - upstream: Import regenerated moduli. + upstream: use 64 bit math to avoid signed underflow. upstream code - OpenBSD-Commit-ID: ad3d1486d105b008c93e952d158e5af4d9d4c531 + relies on using -fwrapv to provide defined over/underflow behaviour, but we + use -ftrapv to catch integer errors and abort the program. ok dtucker@ + + OpenBSD-Commit-ID: 8933369b33c17b5f02479503d0a92d87bc3a574b -commit 151146f03b490d19145cd421763aa7d42f5c50e2 -Author: job@openbsd.org -Date: Thu Mar 14 06:23:14 2024 +0000 +commit f82e5e22cad88c81d8a117de74241328c7b101c3 +Author: jmc@openbsd.org +Date: Sun Sep 15 08:27:38 2024 +0000 - upstream: Clarify how literal IPv6 addresses can be used in -J mode - - OK djm@ + upstream: minor grammar/sort fixes for refuseconnection; ok djm - OpenBSD-Commit-ID: 524ddae97746b3563ad4a887dfd0a6e6ba114c50 + OpenBSD-Commit-ID: 1c81f37b138b8b66abba811fec836388a0f3e6da -commit 0d5bdc87a675271862b67eb6a9fb13a202fb4894 -Author: Darren Tucker -Date: Mon Mar 25 16:14:21 2024 +1100 +commit 0c1165fc78e8fe69b5df71f81a8f944554a68b53 +Author: Damien Miller +Date: Sun Sep 15 13:30:13 2024 +1000 - Add Mac OS X 14 test targets. + avoid gcc warning in fuzz test -commit 2d7964a03e1f50a48040ec6912c0a956df909d21 -Author: Darren Tucker -Date: Mon Mar 25 14:05:40 2024 +1100 +commit ce171d0718104b643854b53443ff72f7283d33f2 +Author: djm@openbsd.org +Date: Sun Sep 15 03:09:44 2024 +0000 - Move xpg4 'id' handling into test-exec.sh. + upstream: bad whitespace in config dump output - Handle replacement of 'id' the same way as we do other Portable specific - replacements in test-exec.sh. This brings percent.sh back into sync - with upstream. + OpenBSD-Commit-ID: d899c13b0e8061d209298eaf58fe53e3643e967c -commit 75d1d49ed10d978171cdafad28bdbffdbd48f41e -Author: Darren Tucker -Date: Mon Mar 25 10:38:03 2024 +1100 +commit 671c440786a5a66216922f15d0007b60f1e6733f +Author: Damien Miller +Date: Sun Sep 15 12:53:59 2024 +1000 - Update branches shown on ci-status to 9.7 and 9.6. + use construct_utmp to construct btmp records + + Simpler and removes some code with the old-style BSD license. -commit f9193f03db0029fc9c31fbdb5c66a2737446bd8f -Author: Darren Tucker -Date: Mon Mar 25 09:28:02 2024 +1100 +commit 930cb02b6113df72fbc732b9feb8e4f490952a81 +Author: djm@openbsd.org +Date: Sun Sep 15 02:20:51 2024 +0000 - Improve detection of -fzero-call-used-regs=used. + upstream: update the Streamlined NTRU Prime code from the "ref" - Should better detect problems with gcc 13 on m68k. bz#3673 from Colin - Watson via bz#3673 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110934 + implementation in SUPERCOP 20201130 to the "compact" implementation in + SUPERCOP 20240808. The new version is substantially faster. Thanks to Daniel + J Bernstein for pointing out the new implementation (and of course for + writing it). - Signed-off-by: Darren Tucker + tested in snaps/ok deraadt@ + + OpenBSD-Commit-ID: bf1a77924c125ecdbf03e2f3df8ad13bd3dafdcb -commit 86bdd3853f4d32c85e295e6216a2fe0953ad93f0 -Author: Damien Miller -Date: Mon Mar 11 16:20:49 2024 +1100 +commit 9306d6017e0ce5dea6824c29ca5ba5673c2923ad +Author: djm@openbsd.org +Date: Sun Sep 15 01:19:56 2024 +0000 - version number in README + upstream: document Match invalid-user + + OpenBSD-Commit-ID: 2c84a9b517283e9711e2812c1f268081dcb02081 -commit 282721418e6465bc39ccfd39bb0133e670ee4423 -Author: Damien Miller -Date: Mon Mar 11 16:20:08 2024 +1100 +commit 0118a4da21147a88a56dc8b90bbc2849fefd5c1e +Author: djm@openbsd.org +Date: Sun Sep 15 01:18:26 2024 +0000 - crank RPM spec versions + upstream: add a "Match invalid-user" predicate to sshd_config Match + + options. + + This allows writing Match conditions that trigger for invalid username. + E.g. + + PerSourcePenalties refuseconnection:90s + Match invalid-user + RefuseConnection yes + + Will effectively penalise bots try to guess passwords for bogus accounts, + at the cost of implicitly revealing which accounts are invalid. + + feedback markus@ + + OpenBSD-Commit-ID: 93d3a46ca04bbd9d84a94d1e1d9d3a21073fbb07 -commit 3876a3bbd2ca84d23ba20f8b69ba83270c04ce3a +commit 7875975136f275619427604900cb0ffd7020e845 Author: djm@openbsd.org -Date: Mon Mar 11 04:59:47 2024 +0000 +Date: Sun Sep 15 01:11:26 2024 +0000 - upstream: openssh-9.7 + upstream: Add a "refuseconnection" penalty class to sshd_config - OpenBSD-Commit-ID: 618ececf58b8cdae016b149787af06240f7b0cbc + PerSourcePenalties + + This allows penalising connection sources that have had connections + dropped by the RefuseConnection option. ok markus@ + + OpenBSD-Commit-ID: 3c8443c427470bb3eac1880aa075cb4864463cb6 -commit 8fc109cc614954a8eb2738c48c0db36a62af9a06 -Author: Darren Tucker -Date: Mon Mar 11 12:59:26 2024 +1100 +commit 8d21713b669b8516ca6d43424a356fccc37212bb +Author: djm@openbsd.org +Date: Sun Sep 15 01:09:40 2024 +0000 - Test against current OpenSSL and LibreSSL releases. + upstream: Add a sshd_config "RefuseConnection" option - Add LibreSSL 3.9.0, bump older branches to their respective current - releases. + If set, this will terminate the connection at the first authentication + request (this is the earliest we can evaluate sshd_config Match blocks) + + ok markus@ + + OpenBSD-Commit-ID: 43cc2533984074c44d0d2f92eb93f661e7a0b09c -commit 26b09b45fec7b88ba09042c09be4157e58e231e2 -Author: Damien Miller -Date: Sun Mar 10 16:24:57 2024 +1100 +commit acad117e66018fe1fa5caf41b36e6dfbd61f76a1 +Author: djm@openbsd.org +Date: Sun Sep 15 00:58:01 2024 +0000 - quote regexes used to test for algorithm support + upstream: switch sshd_config Match processing to the argv tokeniser - Fixes test failures on Solaris 8 reported by Tom G. Christensen + too; ok markus@ + + OpenBSD-Commit-ID: b74b5b0385f2e0379670e2b869318a65b0bc3923 -commit a6a740a4948d10a622b505135bb485c10f21db5e +commit baec3f7f4c60cd5aa1bb9adbeb6dfa4a172502a8 Author: djm@openbsd.org -Date: Sat Mar 9 05:12:13 2024 +0000 +Date: Sun Sep 15 00:57:36 2024 +0000 - upstream: avoid logging in signal handler by converting mainloop to + upstream: switch "Match" directive processing over to the argv - ppoll() bz3670, reported by Ben Hamilton; ok dtucker@ + string tokeniser, making it possible to use shell-like quoting in Match + directives, particularly "Match exec". ok markus@ - OpenBSD-Commit-ID: e58f18042b86425405ca09e6e9d7dfa1df9f5f7f + OpenBSD-Commit-ID: 0877309650b76f624b2194c35dbacaf065e769a5 -commit cd82f7526e0481720567ae41db7849ab1c27e27b +commit dd424d7c382c2074ab70f1b8ad4f169a10f60ee7 Author: djm@openbsd.org -Date: Fri Mar 8 22:16:32 2024 +0000 +Date: Sun Sep 15 00:47:01 2024 +0000 - upstream: skip more whitespace, fixes find-principals on + upstream: include pathname in some of the ssh-keygen passphrase - allowed_signers files with blank lines; reported by Wiktor Kwapisiewicz + prompts. Helps the user know what's going on when ssh-keygen is invoked via + other tools. Requested in GHPR503 - OpenBSD-Commit-ID: b3a22a2afd753d70766f34bc7f309c03706b5298 + OpenBSD-Commit-ID: 613b0bb6cf845b7e787d69a5b314057ceda6a8b6 -commit 2f9d2af5cb19905d87f37d1e11c9f035ac5daf3b -Author: dtucker@openbsd.org -Date: Fri Mar 8 11:34:10 2024 +0000 +commit 62bbf8f825cc390ecb0523752ddac1435006f206 +Author: djm@openbsd.org +Date: Sun Sep 15 00:41:18 2024 +0000 - upstream: Invoke ProxyCommand that uses stderr redirection via + upstream: Do not apply authorized_keys options when signature - $TEST_SHELL. Fixes test when run by a user whose login shell is tcsh. - Found by vinschen at redhat.com. + verification fails. Prevents restrictive key options being incorrectly + applied to subsequent keys in authorized_keys. bz3733, ok markus@ - OpenBSD-Regress-ID: f68d79e7f00caa8d216ebe00ee5f0adbb944062a + OpenBSD-Commit-ID: ba3776d9da4642443c19dbc015a1333622eb5a4e -commit 9b3f0beb4007a7e01dfedabb429097fb593deae6 -Author: Darren Tucker -Date: Thu Mar 7 17:18:14 2024 +1100 +commit 49f325fd47af4e53fcd7aafdbcc280e53f5aa5ce +Author: Wu Weixin +Date: Fri Aug 2 22:16:40 2024 +0800 - Prefer openssl binary from --with-ssl-dir directory. + Fix without_openssl always being set to 1 - Use openssl in the directory specified by --with-ssl-dir as long - as it's functional. Reported by The Doctor. + In Fedora systems, %{?rhel} is empty. In RHEL systems, %{?fedora} is + empty. Therefore, the original code always sets without_openssl to 1. -commit c47e1c9c7911f38b2fc2fb01b1f6ae3a3121a838 +commit c21c3a2419bbc1c59cb1a16ea356e703e99a90d9 Author: djm@openbsd.org -Date: Wed Mar 6 02:59:59 2024 +0000 +Date: Thu Sep 12 00:36:27 2024 +0000 - upstream: fix memory leak in mux proxy mode when requesting forwarding. + upstream: Relax absolute path requirement back to what it was prior to - found by RASU JSC, reported by Maks Mishin in GHPR#467 + OpenSSH 9.8, which incorrectly required that sshd was started with an + absolute path in inetd mode. bz3717, patch from Colin Wilson - OpenBSD-Commit-ID: 97d96a166b1ad4b8d229864a553e3e56d3116860 + OpenBSD-Commit-ID: 25c57f22764897242d942853f8cccc5e991ea058 -commit 242742827fea4508e68097c128e802edc79addb5 -Author: djm@openbsd.org -Date: Wed Mar 6 00:31:04 2024 +0000 +commit 1bc426f51b0a5cfdcfbd205218f0b6839ffe91e9 +Author: naddy@openbsd.org +Date: Mon Sep 9 14:41:21 2024 +0000 - upstream: wrap a few PKCS#11-specific bits in ENABLE_PKCS11 + upstream: document the mlkem768x25519-sha256 key exchange algorithm - OpenBSD-Commit-ID: 463e4a69eef3426a43a2b922c4e7b2011885d923 + OpenBSD-Commit-ID: fa18dccdd9753dd287e62ecab189b3de45672521 -commit d52b6509210e2043f33e5a1de58dd4a0d5d48c2a +commit 0a2db61a5ffc64d2e2961c52964f933879952fc7 +Author: Darren Tucker +Date: Tue Sep 10 21:11:14 2024 +1000 + + Spell omnios test host correctly. + +commit 059ed698a47c9af541a49cf754fd09f984ac5a21 +Author: Darren Tucker +Date: Tue Sep 10 18:52:02 2024 +1000 + + Add omnios test target. + +commit f4ff91575a448b19176ceaa8fd6843a25f39d572 +Author: Darren Tucker +Date: Tue Sep 10 18:45:55 2024 +1000 + + Wrap stdint.h in ifdef. + +commit ff714f001d20a9c843ee1fd9d92a16d40567d264 +Author: Darren Tucker +Date: Mon Sep 9 19:31:54 2024 +1000 + + Also test PAM on dfly64. + +commit 509b757c052ea969b3a41fc36818b44801caf1cf Author: Damien Miller -Date: Wed Mar 6 11:31:36 2024 +1100 +Date: Mon Sep 9 21:50:14 2024 +1000 - disable RSA tests when algorithm is not supported + stubs for ML-KEM KEX functions - Unbreaks "make test" when compiled --without-openssl. + used for C89 compilers + +commit 273581210c99ce7275b8efdefbb9f89e1c22e341 +Author: Damien Miller +Date: Mon Sep 9 17:30:38 2024 +1000 + + declare defeat trying to detect C89 compilers - Similar treatment to how we do DSA and ECDSA. + I can't find a reliable way to detect the features the ML-KEM code + requires in configure. Give up for now and use VLA support (that we + can detect) as a proxy for "old compiler" and turn off ML-KEM if + it isn't supported. -commit 668d270a6c77e8b5a1da26ecad2e6de9f62c8fe4 +commit e8a0f19b56dfa20f98ea9876d7171ec315fb338a Author: Damien Miller -Date: Wed Mar 6 10:33:20 2024 +1100 +Date: Mon Sep 9 16:46:40 2024 +1000 - add a --without-retpoline configure option + fix previous; check for C99 compound literals - discussed with deraadt and dtucker a while ago + The previous commit was incorrect (or at least insufficient), the + ML-KEM code is actually using compound literals, so test for them. -commit 3deb501f86fc47e175ef6a3eaba9b9846a80d444 -Author: djm@openbsd.org -Date: Mon Mar 4 04:13:18 2024 +0000 +commit 7c07bec1446978bebe0780ed822c8fedfb377ae8 +Author: Damien Miller +Date: Mon Sep 9 16:06:21 2024 +1000 - upstream: fix leak of CanonicalizePermittedCNAMEs on error path; + test for compiler feature needed for ML-KEM - spotted by Coverity (CID 438039) + The ML-KEM implementation we uses need the compiler to support + C99-style named struct initialisers (e.g foo = {.bar = 1}). We + still support (barely) building OpenSSH with older compilers, so + add a configure test for this. + +commit d469d5f348772058789d35332d1ccb0b109c28ef +Author: djm@openbsd.org +Date: Mon Sep 9 03:13:39 2024 +0000 + + upstream: test mlkem768x25519-sha256 - OpenBSD-Commit-ID: 208839699939721f452a4418afc028a9f9d3d8af + OpenBSD-Regress-ID: 7baf6bc39ae55648db1a2bfdc55a624954847611 -commit 65a44a8a4f7d902a64d4e60eda84384b2e2a24a2 +commit 62fb2b51bb7f6863c3ab697f397b2068da1c993f Author: djm@openbsd.org -Date: Mon Mar 4 02:16:11 2024 +0000 +Date: Mon Sep 9 02:39:57 2024 +0000 - upstream: Separate parsing of string array options from applying them + upstream: pull post-quantum ML-KEM/x25519 key exchange out from - to the active configuration. This fixes the config parser from erroneously - rejecting cases like: + compile-time flag now than an IANA codepoint has been assigned for the + algorithm. - AuthenticationMethods password - Match User ivy - AuthenticationMethods any + Add mlkem768x25519-sha256 in 2nd KexAlgorithms preference slot. - bz3657 ok markus@ + ok markus@ - OpenBSD-Commit-ID: 7f196cba634c2a3dba115f3fac3c4635a2199491 - -commit 6886e1b1f55c90942e4e6deed930f8ac32e0f938 -Author: Darren Tucker -Date: Thu Feb 22 17:59:35 2024 +1100 - - Add nbsd10 test target. - -commit d86bf8a3f6ea4fa7887406c2aa9959db71fa41be -Author: Damien Miller -Date: Thu Feb 22 12:06:10 2024 +1100 - - more descriptive configure test name + OpenBSD-Commit-ID: 9f50a0fae7d7ae8b27fcca11f8dc6f979207451a -commit 9ee335aacc9f5bdc4cc2c19fafb45e27be7d234e +commit a8ad7a2952111c6ce32949a775df94286550af6b Author: djm@openbsd.org -Date: Wed Feb 21 06:17:29 2024 +0000 +Date: Fri Sep 6 02:30:44 2024 +0000 - upstream: explain arguments of internal-sftp GHPR#454 from Niklas + upstream: make parsing user@host consistently look for the last '@' in - Hambüchen + the string rather than the first. This makes it possible to use usernames + that contain '@' characters. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - OpenBSD-Commit-ID: 0335d641ae6b5b6201b9ffd5dd06345ebbd0a3f3 + Prompted by Max Zettlmeißl; feedback/ok millert@ + + OpenBSD-Commit-ID: 0b16eec246cda15469ebdcf3b1e2479810e394c5 -commit d1164cb1001dd208fee88aaa9b43d5e6fd917274 +commit 13cc78d016b67a74a67f1c97c7c348084cd9212c Author: djm@openbsd.org -Date: Wed Feb 21 06:06:43 2024 +0000 +Date: Wed Sep 4 05:33:34 2024 +0000 - upstream: clarify permissions requirements for ChrootDirectory Part + upstream: be more strict in parsing key type names. Only allow - of GHPR#454 from Niklas Hambüchen - MIME-Version: 1.0 - Content-Type: text/plain; charset=UTF-8 - Content-Transfer-Encoding: 8bit + shortnames (e.g "rsa") in user-interface code and require full SSH protocol + names (e.g. "ssh-rsa") everywhere else. - OpenBSD-Commit-ID: d37bc8786317a11649c62ff5e2936441186ef7a0 + Prompted by bz3725; ok markus@ + + OpenBSD-Commit-ID: b3d8de9dac37992eab78adbf84fab2fe0d84b187 -commit d410e17d186552d0717f18217d0d049486754365 +commit ef8472309a68e319018def6f8ea47aeb40d806f5 Author: djm@openbsd.org -Date: Wed Feb 21 06:05:06 2024 +0000 +Date: Wed Sep 4 05:11:33 2024 +0000 - upstream: .Cm for a keyword. Part of GHPR#454 from Niklas Hambüchen + upstream: fix RCSID in output - OpenBSD-Commit-ID: d59c52559f926fa82859035d79749fbb4a3ce18a + OpenBSD-Commit-ID: 889ae07f2d2193ddc4351711919134664951dd76 -commit ab73f9678ebf06b32d6361b88b50b42775e0565b -Author: djm@openbsd.org -Date: Wed Feb 21 06:01:13 2024 +0000 +commit ba2ef20c75c5268d4d1257adfc2ac11c930d31e1 +Author: jmc@openbsd.org +Date: Tue Sep 3 06:17:48 2024 +0000 - upstream: fix typo in match directive predicate (s/tagged/tag) GHPR#462 - - from Tobias Manske + upstream: envrionment -> environment; - OpenBSD-Commit-ID: 05b23b772677d48aa82eefd7ebebd369ae758908 + OpenBSD-Commit-ID: b719f39c20e8c671ec6135c832d6cc67a595af9c -commit 9844aa2521ccfb1a2d73745680327b79e0574445 -Author: djm@openbsd.org -Date: Wed Feb 21 05:57:34 2024 +0000 +commit e66c0c5673a4304a3a9fbf8305c6a19f8653740f +Author: Damien Miller +Date: Wed Sep 4 15:35:29 2024 +1000 - upstream: fix proxy multiplexing mode, broken when keystroke timing - - obfuscation was added. GHPR#463 from montag451 + add basic fuzzers for our import of sntrup761 + +commit d19dea6330ecd4eb403fef2423bd7e127f4c9828 +Author: djm@openbsd.org +Date: Tue Sep 3 05:58:56 2024 +0000 + + upstream: regression test for Include variable expansion - OpenBSD-Commit-ID: 4e412d59b3f557d431f1d81c715a3bc0491cc677 + OpenBSD-Regress-ID: 35477da3ba1abd9ca64bc49080c50a9c1350c6ca -commit ee6d932acb532f80b11bb7cf161668c70ec8a117 +commit 8c4d6a628051e318bae2f283e8dc38b896400862 Author: djm@openbsd.org -Date: Tue Feb 20 04:10:03 2024 +0000 +Date: Tue Sep 3 05:29:55 2024 +0000 - upstream: don't append a gratuitous space to the end of subsystem + upstream: allow the "Include" directive to expand the same set of - arguments; bz3667 + %-tokens that "Match Exec" and environment variables. - OpenBSD-Commit-ID: e11023aeb3f30b77a674e37b8292c862926d5dc6 + ok dtucker@ + + OpenBSD-Commit-ID: 12ef521eaa966a9241e684258564f52f1f3c5d37 -commit e27f032aa8fcbae9b2e7c451baaf4b8ac6fa3d45 -Author: dtucker@openbsd.org -Date: Mon Feb 19 09:25:52 2024 +0000 +commit 51b82648b6827675fc0cde21175fd1ed8e89aab2 +Author: djm@openbsd.org +Date: Mon Sep 2 12:18:35 2024 +0000 - upstream: Always define puttysetup function. + upstream: missing ifdef - OpenBSD-Regress-ID: b4c0ccfa4006a1bc5dfd99ccf21c854d3ce2aee0 + OpenBSD-Commit-ID: 85f09da957dd39fd0abe08fe5ee19393f25c2021 -commit 84046f9991abef5f46b040b10cf3d494f933a17b -Author: dtucker@openbsd.org -Date: Fri Feb 9 08:56:59 2024 +0000 +commit f68312eb593943127b39ba79a4d7fa438c34c153 +Author: djm@openbsd.org +Date: Mon Sep 2 12:13:56 2024 +0000 - upstream: Exapnd PuTTY test coverage. + upstream: Add experimental support for hybrid post-quantum key exchange - Expand the set of ciphers, MACs and KEX methods in the PuTTY interop - tests. + ML-KEM768 with ECDH/X25519 from the Internet-draft: + https://datatracker.ietf.org/doc/html/draft-kampanakis-curdle-ssh-pq-ke-03 - OpenBSD-Regress-ID: dd28d97d48efe7329a396d0d505ee2907bf7fc57 - -commit bbf541ee2afe07b08a8b56fa0dc6f38fcfceef2a -Author: dtucker@openbsd.org -Date: Fri Feb 9 08:47:42 2024 +0000 - - upstream: Factor out PuTTY setup. + This is based on previous patches from markus@ but adapted to use the + final FIPS203 standard ML-KEM using a formally-verified implementation + from libcrux. - Factor out PuTTY and call only when needed. + Note this key exchange method is still a draft and thus subject to + change. It is therefore disabled by default; set MLKEM=yes to build it. + We're making it available now to make it easy for other SSH + implementations to test against it. - This allows us to avoid PuTTY key setup when it's not needed, which - speeds up the overall test run by a couple of percent. + ok markus@ deraadt@ - OpenBSD-Regress-ID: c25eaccc3c91bc874400f7c85ce40e9032358c1c + OpenBSD-Commit-ID: 02a8730a570b63fa8acd9913ec66353735dea42c -commit d31c21c57fb4245271680a1e5043cf6470a96766 -Author: naddy@openbsd.org -Date: Sat Feb 10 11:28:52 2024 +0000 +commit 05f2b141cfcc60c7cdedf9450d2b9d390c19eaad +Author: Antonio Larrosa +Date: Fri Aug 23 12:21:06 2024 +0200 - upstream: clean sshd random relinking kit; ok miod@ + Don't skip audit before exitting cleanup_exit - OpenBSD-Commit-ID: 509bb19bb9762a4b3b589af98bac2e730541b6d4 + This fixes an issue where the SSH_CONNECTION_ABANDON event is not + audited because cleanup_exit overrides the regular _exit too soon and + as a result, failed auth attempts are not logged correctly. + + The problem was introduced in 81c1099d22b81ebfd20a334ce986c4f753b0db29 + where the code from upstream was merged before the audit_event call when + it should have been merged right before the _exit call in order to honor + the comment that just mentions an override of the exit value. -commit 4dbc5a363ff53a2fcecf6bc3bcc038badc12f118 +commit 16eaf9d401e70996f89f3f417738a8db421aa959 Author: djm@openbsd.org -Date: Fri Feb 2 00:13:34 2024 +0000 +Date: Wed Aug 28 12:08:26 2024 +0000 - upstream: whitespace + upstream: fix test: -F is the argument to specify a non-default - OpenBSD-Commit-ID: b24680bc755b621ea801ff8edf6f0f02b68edae1 - -commit efde85dda2130272af24cc346f6c3cd326182ff1 -Author: Darren Tucker -Date: Mon Feb 19 17:29:31 2024 +1100 - - Improve error message for OpenSSL header check. + ssh_config, not -f (this is sadly not a new bug) - bz#3668, ok djm@ + OpenBSD-Regress-ID: 45a7bda4cf33f2cea218507d8b6a55cddbcfb322 -commit cbbdf868bce431a59e2fa36ca244d5739429408d -Author: Darren Tucker -Date: Wed Feb 7 13:45:02 2024 +1100 +commit 10ccf611ab8ecba9ce6b0548c5ccd8c1220baf92 +Author: deraadt@openbsd.org +Date: Fri Aug 23 04:51:00 2024 +0000 - Interop test against PuTTY snapshot and releases. + upstream: As defined in the RFC, the SSH protocol has negotiable + + compression support (which is requested as the name "zlib"). Compression + starts very early in the session. Relative early in OpenSSH lifetime, privsep + was added to sshd, and this required a shared-memory hack so the two + processes could see what was going on in the dataflow. This shared-memory + hack was soon recognized as a tremendous complexity risk, because it put libz + (which very much trusts it's memory) in a dangerous place, and a new option + ("zlib@openssh.com") was added begins compression after authentication (aka + delayed-compression). That change also permitted removal of the + shared-memory hack. Despite removal from the server, the old "zlib" support + remained in the client, to allow negotiation with non-OpenSSH daemons which + lack the delayed-compression option. This commit deletes support for the + older "zlib" option in the client. It reduces our featureset in a small way, + and encourages other servers to move to a better design. The SSH protocol is + different enough that compressed-key-material attacks like BEAST are + unlikely, but who wants to take the chance? We encourage other ssh servers + who care about optional compression support to add delayed-zlib support. + (Some already do "zlib@openssh.com") ok djm markus + + OpenBSD-Commit-ID: 6df986f38e4ab389f795a6e39e7c6857a763ba72 -commit 91898bf786b0f149f962c4c96c08a46f29888c10 -Author: Darren Tucker -Date: Tue Feb 6 16:21:05 2024 +1100 +commit aee54878255d71bf93aa6e91bbd4eb1825c0d1b9 +Author: djm@openbsd.org +Date: Thu Aug 22 23:11:30 2024 +0000 - Put privsep dir on OS X on /usr/local. + upstream: sntrup761x25519-sha512 now has an IANA codepoint assigned, so - On some runners we can't create /var/empty, so put it some place we can - write. Should fix test breakage on Max OS X 11. + we can make the algorithm available without the @openssh.com suffix too. ok + markus@ deraadt@ + + OpenBSD-Commit-ID: eeed8fcde688143a737729d3d56d20ab4353770f -commit be5ed8ebed8388c5056bfde4688308cc873c18b9 +commit a76a6b85108e3032c8175611ecc5746e7131f876 Author: Darren Tucker -Date: Tue Feb 6 11:19:42 2024 +1100 +Date: Thu Aug 22 20:36:12 2024 +1000 - Add --disable-fd-passing option. + Move rekey test into valgrind-2. - .. and enable for the minix3 test VM. This will cause it to more reliably - skip tests that need FD passing and should fix the current test breakage. + Now that the rekey test has been optimized it's fast enough to not be in + its own valgrind test, so move it into valgrind-2, which is currently + the quickest of the others, bringing all of them to roughly the same + runtime of ~1.1 hours. -commit 0f6a8a0d0a518fd78c4cbebfdac990a57a1c4e41 -Author: Darren Tucker -Date: Tue Feb 6 11:18:44 2024 +1100 +commit 7e75e3f57c41b9a6e6401e7674d7c2ff5c33975b +Author: dtucker@openbsd.org +Date: Thu Aug 22 10:21:02 2024 +0000 - Use "skip" function instead doing it ourselves. + upstream: Use aes128-ctr for MAC tests since default has implicit MAC. + + Also verify that the Cipher or MAC we intended to use is actually the one + selected during the test. + + OpenBSD-Regress-ID: ff43fed30552afe23d1364526fe8cf88cbfafe1d -commit 3ad669f81aabbd2ba9fbd472903f680f598e1e99 +commit ebc890b8b4ba08c84cd1066b7b94b2b11f6c4cb4 Author: Damien Miller -Date: Thu Feb 1 14:01:18 2024 +1100 +Date: Thu Aug 22 09:45:49 2024 +1000 - ignore some vim droppings + fix incorrect default for PasswordAuthentication + + merge botch spotted by gsgleason -commit c283f29d23611a06bbee06bcf458f2fffad721d9 -Author: djm@openbsd.org -Date: Thu Feb 1 02:37:33 2024 +0000 +commit 15ace435ea1c2fab2a1cc7d9c3157fe20c776b80 +Author: dtucker@openbsd.org +Date: Wed Aug 21 10:33:27 2024 +0000 - upstream: whitespace + upstream: Some awks won't match on the \r so delete it instead. Fixes - OpenBSD-Commit-ID: bf9e4a1049562ee4322684fbdce07142f04fdbb7 + regress in portable on, eg Solaris. + + OpenBSD-Regress-ID: 44a96d6d2f8341d89b7d5fff777502b92ac9e9ba -commit 0d96b1506b2f4757fefa5d1f884d49e96a6fd4c3 -Author: Damien Miller -Date: Tue Jan 16 14:40:18 2024 +1100 +commit 51c96b6ed627779a04493a8fe25747996a37f3c2 +Author: dtucker@openbsd.org +Date: Wed Aug 21 07:06:27 2024 +0000 - skip tests that use multiplexing on Windows + upstream: Import regenerated moduli. - Some tests here use multiplexing, skip these if DISABLE_FD_PASSING - is set. Should unbreak tests on Windows. + OpenBSD-Commit-ID: 5db7049ad5558dee5b2079d3422e8ddab187c1cc -commit 50080fa42f5f744b798ee29400c0710f1b59f50e -Author: djm@openbsd.org -Date: Thu Jan 11 04:50:28 2024 +0000 +commit 25c52f37a82c4da48ec537de37d7c168982b8d6d +Author: dtucker@openbsd.org +Date: Wed Aug 21 06:59:08 2024 +0000 - upstream: don't disable RSA test when DSA is disabled; bug introduced + upstream: Use curve25519-sha256 kex where possible. - in last commit + Except where we're explicitly testing a different kex, use + curve25519-sha256 since it's faster than the default and supported even + when configured without OpenSSL. Add a check to ensure that the kex we + intended to test is the one we actually tested. Speeds test up by ~5%. - OpenBSD-Regress-ID: 8780a7250bf742b33010e9336359a1c516f2d7b5 + OpenBSD-Regress-ID: 3b27fcc2ae953cb08fd82a0d3155c498b226d6e0 -commit 415c94ce17288e0cdcb9e58cc91fba78d33c8457 -Author: djm@openbsd.org -Date: Thu Jan 11 01:45:58 2024 +0000 +commit 3eb62b7ba49483c309b483eb9002a679014f3887 +Author: dtucker@openbsd.org +Date: Tue Aug 20 12:36:59 2024 +0000 - upstream: make DSA testing optional, defaulting to on + upstream: Send only as much data as needed to trigger rekeying. Speeds - ok markus + up tests by about 10% in the common case, hopefully more when instrumented + with something like valgrind. - OpenBSD-Regress-ID: dfc27b5574e3f19dc4043395594cea5f90b8572a + OpenBSD-Regress-ID: 7bf9292b4803357efcf0baf7cfbdc8521f212da1 -commit f9311e8921d92c5efca767227a497ab63280ac39 -Author: djm@openbsd.org -Date: Thu Jan 11 01:51:16 2024 +0000 +commit cbd3f034bbf7853618fac99d7d868a2250154ea7 +Author: Damien Miller +Date: Wed Aug 21 09:18:29 2024 +1000 - upstream: ensure key_fd is filled when DSA is disabled; spotted by - - tb@ - - OpenBSD-Commit-ID: 9dd417b6eec3cf67e870f147464a8d93f076dce7 + simplify sshkey_prekey_alloc(); always use mmap -commit 4e838120a759d187b036036610402cbda33f3203 -Author: djm@openbsd.org -Date: Thu Jan 11 01:45:36 2024 +0000 +commit 4442bbc2fc661277a6dabfedb756a7e15ee8b8b8 +Author: dtucker@openbsd.org +Date: Tue Aug 20 09:15:49 2024 +0000 - upstream: make DSA key support compile-time optional, defaulting to - - on + upstream: Merge AEAD test into main test loop. - ok markus@ + Removes 3 duplicate tests and speeds overall test up by about 1%. - OpenBSD-Commit-ID: 4f8e98fc1fd6de399d0921d5b31b3127a03f581d + OpenBSD-Regress-ID: 5e5c9ff3f7588091ed369e34ac28520490ad2619 -commit afcc9028bfc411bc26d20bba803b83f90cb84e26 -Author: jmc@openbsd.org -Date: Wed Jan 10 06:33:13 2024 +0000 +commit 829976a63fd1efae3a4c3e7c16fded59d92edb67 +Author: dtucker@openbsd.org +Date: Tue Aug 20 09:02:45 2024 +0000 - upstream: fix incorrect capitalisation; + upstream: Set a default RekeyLimit of 256k. - OpenBSD-Commit-ID: cb07eb06e15fa2334660ac73e98f29b6a1931984 + Used unless overridden by a command-line flag, which simplifies some of + the ssh command lines. + + OpenBSD-Regress-ID: e7cffa57027088e10336e412b34113969f88cb87 -commit 9707c8170c0c1baeb1e06e5a53f604498193885f -Author: djm@openbsd.org -Date: Tue Jan 9 22:19:36 2024 +0000 +commit 57d02c9ea36aebad4e7146d46e041b6b2e582f7f +Author: dtucker@openbsd.org +Date: Tue Aug 20 07:52:43 2024 +0000 - upstream: extend ChannelTimeout regression test to exercise multiplexed + upstream: Add Compression=no to default ssh_config. - connections and the new "global" timeout type. ok dtucker@ + All of the rekey tests use it (otherwise the encrypted byte counts would + not match) so this lets us simplify the command lines. - OpenBSD-Regress-ID: f10d19f697024e9941acad7c2057f73d6eacb8a2 + OpenBSD-Regress-ID: dab7ce10f4cf6c68827eb8658141272aab3ea262 -commit b31b12d28de96e1d43581d32f34da8db27e11c03 -Author: djm@openbsd.org -Date: Tue Jan 9 22:19:00 2024 +0000 +commit 7254eb26f7c0772c4b47c3b32f6d1b15855cdd8c +Author: dtucker@openbsd.org +Date: Tue Aug 20 07:41:35 2024 +0000 - upstream: add a "global" ChannelTimeout type to ssh(1) and sshd(8) + upstream: Remove duplicate curve25519-sha256 kex. - that watches all open channels and will close all open channels if there is - no traffic on any of them for the specified interval. This is in addition to - the existing per-channel timeouts added a few releases ago. + curve25519-sha256@libssh.org is the pre-standardization name for the same + thing, so remove it as a duplicate. Speeds up test by a tiny amount. - This supports use-cases like having a session + x11 forwarding channel - open where one may be idle for an extended period but the other is - actively used. The global timeout would allow closing both channels when - both have been idle for too long. + OpenBSD-Regress-ID: 5a5ee5fa1595a6e140b1cc16040bedf5996a5715 + +commit 749896b874928c2785256cae4d75161dc3bfcc7d +Author: dtucker@openbsd.org +Date: Tue Aug 20 07:27:25 2024 +0000 + + upstream: Unnest rekey param parsing test and use ssh not sshd. - ok dtucker@ + ssh uses the same parsing code, now has "-G" to dump its config and is + slightly faster to start up. This speeds up the test slightly (~5%) in the + common case but should help more during instrumented tests, eg under + valgrind, where startup costs are magnified. - OpenBSD-Commit-ID: 0054157d24d2eaa5dc1a9a9859afefc13d1d7eb3 + OpenBSD-Regress-ID: 07c3acaf4c728e641033071f4441afc88141b0d0 -commit 602f4beeeda5bb0eca181f8753d923a2997d0a51 +commit 2b1762115481ff2b7a60fd4db2ae69b725437462 Author: djm@openbsd.org -Date: Tue Jan 9 21:39:14 2024 +0000 +Date: Tue Aug 20 11:10:04 2024 +0000 - upstream: adapt ssh_api.c code for kex-strict + upstream: actually use the length parameter that was passed in rather - from markus@ ok me + than a constant (this makes no difference in practice because the length is + always the same); reported by martin AT nmkd.net - OpenBSD-Commit-ID: 4d9f256852af2a5b882b12cae9447f8f00f933ac + OpenBSD-Commit-ID: 4aecce232c2fe9b16e9217ff6bcb3c848d853e7e -commit 42ba34aba8708cf96583ff52975d95a8b47d990d +commit d922762ca16a7381131b242f49d7376c41fabcb5 Author: Damien Miller -Date: Mon Jan 8 16:26:37 2024 +1100 - - nite that recent OSX tun/tap is unsupported - -commit 690bc125f9a3b20e47745fa8f5b5e1fd5820247f -Author: Sevan Janiyan -Date: Wed Dec 27 04:57:49 2023 +0000 - - README.platform: update tuntap url - -commit 6b8be2ccd7dd091808f86af52066b0c2ec30483a -Author: Rose <83477269+AtariDreams@users.noreply.github.com> -Date: Tue Dec 19 11:48:20 2023 -0500 +Date: Tue Aug 20 13:55:30 2024 +1000 - Fix compilation error in ssh-pcks11-client.c + private key coredump protection for Linux/FreeBSD - Compilation fails becaus of an undefined reference to helper_by_ec, - because we forgot the preprocessor conditional that excludes that function - from being called in unsupported configurations. + platforms not supporting coredump exclusion using mmap/madvise flags + fall back to plain old malloc(3). -commit 219c8134157744886ee6ac5b8c1650abcd981f4c +commit cc048ca536d6bed6f2285b07040b0d57cd559ba5 Author: djm@openbsd.org -Date: Mon Jan 8 05:11:18 2024 +0000 +Date: Tue Aug 20 03:48:30 2024 +0000 - upstream: Remove outdated note from PROTOCOL.mux + upstream: place shielded keys (i.e. keys at rest in RAM) into memory - Port forward close by control master is already implemented - by `mux_master_process_close_fwd` in `mux.c` + allocated using mmap(3) with MAP_CONCEAL set. This prevents exposure of the + key material in coredumps, etc (this is in addition to other measures we take + in this area). - GHPR442 from bigb4ng + ok deraadt@ - OpenBSD-Commit-ID: ad0734fe5916d2dc7dd02b588906cea4df0482fb + OpenBSD-Commit-ID: cbbae59f337a00c9858d6358bc65f74e62261369 -commit 4c3cf362631ccc4ffd422e572f075d5d594feace +commit a0b35c791cad1f85481b23ba46373060292e1c80 Author: djm@openbsd.org -Date: Mon Jan 8 05:05:15 2024 +0000 +Date: Sat Aug 17 08:35:04 2024 +0000 - upstream: fix missing field in users-groups-by-id@openssh.com reply - - documentation + upstream: mention that ed25519 is the default key type generated and - GHPR441 from TJ Saunders + clarify that rsa-sha2-512 is the default signature scheme when RSA is in use. + Based on GHPR505 from SebastianRzk - OpenBSD-Commit-ID: ff5733ff6ef4cd24e0758ebeed557aa91184c674 + OpenBSD-Commit-ID: 1d90df71636a04601685d2a10a8233bcc8d4f4c5 -commit f64cede2a3c298b50a2659a8b53eb3ab2c0b8d23 +commit 127a50f2c80572ed1a021feb11ecf941e92cbbef Author: djm@openbsd.org -Date: Mon Jan 8 04:10:03 2024 +0000 +Date: Sat Aug 17 08:23:04 2024 +0000 - upstream: make kex-strict section more explicit about its intent: + upstream: fix minor memory leak in Subsystem option parsing; from - banning all messages not strictly required in KEX + Antonio Larrosa via GHPR515 - OpenBSD-Commit-ID: fc33a2d7f3b7013a7fb7500bdbaa8254ebc88116 + OpenBSD-Commit-ID: fff3bbefd1b2c45c98cbe45c6b857b15d8a2d364 -commit 698fe6fd61cbcb8e3e0e874a561d4335a49fbde5 -Author: Damien Miller -Date: Mon Jan 8 14:46:19 2024 +1100 +commit 171427261d2079941eb1041079dbae875da37cbc +Author: djm@openbsd.org +Date: Sat Aug 17 08:09:50 2024 +0000 - update fuzzer example makefile to clang16 + upstream: fix swapping of source and destination addresses in some sshd + + log messages + + OpenBSD-Commit-ID: 24d4cbb86325275df1f037545aa3b91456e52d25 -commit fc332cb2d602c60983a8ec9f89412754ace06425 -Author: Damien Miller -Date: Mon Jan 8 14:45:49 2024 +1100 +commit 2a50a8f1fa57857a5e124a2280bcf61cc63c77f7 +Author: Darren Tucker +Date: Sat Aug 17 11:10:19 2024 +1000 - unbreak fuzzers - missing pkcs11_make_cert() + Add compat functions for EVP_Digest{Sign,Verify}. - provide stub for use in fuzzer harness + This should make LibreSSL 3.1.x through 3.3.x work again. Code from + tb@, ok djm@. Restore the test configs covering those. -commit 9ea0a4524ae3276546248a926b6641b2fbc8421b -Author: Damien Miller -Date: Mon Jan 8 14:45:14 2024 +1100 +commit 1c3a7145260e03037cc18715b883880836fd122d +Author: Philip Hands +Date: Thu Aug 8 13:03:51 2024 +0200 - unbreak fuzzers for clang16 + make sure that usage & man page match - getopt() needs a throw() attribute to compile, so supply one when compiling - things with C++ + SSH-Copy-ID-Upstream: da5b1abe55b72a16e0430e7598e1573da01779c0 -commit a72833d00788ef91100c643536ac08ada46440e1 -Author: djm@openbsd.org -Date: Mon Jan 8 00:34:33 2024 +0000 +commit cd0d681645b9adcf2467e7838bfd9d5142de4c4e +Author: Philip Hands +Date: Thu Aug 8 13:01:47 2024 +0200 - upstream: remove ext-info-* in the kex.c code, not in callers; + update copyright notices - with/ok markus@ + Bump the year to 2024, but also reflect the fact that hands.com Ltd. has + been wound up in the UK, and its assets (including this copyright) have + now reverted to its owner, Philip Hands. - OpenBSD-Commit-ID: c06fe2d3a0605c517ff7d65e38ec7b2d1b0b2799 + SSH-Copy-ID-Upstream: 0e4c4d072747a6568b11a790c29dd1b4ce663d7f -commit 86f9e96d9bcfd1f5cd4bf8fb57a9b4c242df67df -Author: djm@openbsd.org -Date: Mon Jan 8 00:30:39 2024 +0000 +commit 7fc9ccdce18841ebd0a97e31e43258512ab32a32 +Author: Philip Hands +Date: Sun Aug 4 20:45:00 2024 +0200 - upstream: fix typo; spotted by Albert Chin + restore optionality of -i's argument - OpenBSD-Commit-ID: 77140b520a43375b886e535eb8bd842a268f9368 + SSH-Copy-ID-Upstream: f70e3abb510e4eeb040b47894e41828246c1b720 -commit f0cbd26ec91bd49719fb3eea7ca44d2380318b9a -Author: dtucker@openbsd.org -Date: Thu Jan 4 09:51:49 2024 +0000 +commit c37aa7012b1a3c2c322fd19e71310aadc90fc674 +Author: Philip Hands +Date: Fri Aug 2 15:52:07 2024 +0200 - upstream: Import regenerated moduli. + avoid exploring .ssh/id*.pub subdirectories - OpenBSD-Commit-ID: 5a636f6ca7f25bfe775df4952f7aac90a7fcbbee + SSH-Copy-ID-Upstream: 0b9e08b7707ad16de3c8e6a0410d9f42fbd56997 -commit 64ddf776531ca4933832beecc8b7ebe1b937e081 -Author: jsg@openbsd.org -Date: Wed Dec 20 00:06:25 2023 +0000 +commit 777dce9e2e0d12f7e81e162f77749f30899869fe +Author: Philip Hands +Date: Fri Aug 2 10:07:11 2024 +0200 - upstream: spelling; ok markus@ + ensure that we're always told the source of keys - OpenBSD-Commit-ID: 9d01f2e9d59a999d5d42fc3b3efcf8dfb892e31b + SSH-Copy-ID-Upstream: 1bee96f4793e8ec3fab9f9361204ae58f5cc7cae -commit 503fbe9ea238a4637e8778208bde8c09bcf78475 -Author: jmc@openbsd.org -Date: Tue Dec 19 06:57:34 2023 +0000 +commit fb94fd2339848e40cad6c9bb42b822244cc1a7bc +Author: Philip Hands +Date: Wed Jul 31 23:19:51 2024 +0200 - upstream: sort -C, and add to usage(); ok djm + add $HOME to ERROR if one cannot write to ~/.ssh - OpenBSD-Commit-ID: 80141b2a5d60c8593e3c65ca3c53c431262c812f + SSH-Copy-ID-Upstream: ebef3e9c06e0447bff06e9d84b33023cf592e0ba -commit 5413b1c7ff5a19c6a7d44bd98c5a83eb47819ba6 -Author: djm@openbsd.org -Date: Tue Dec 19 06:41:14 2023 +0000 +commit eb5aafa1ffaeee75799141ec5ded406a65ec7d18 +Author: Philip Hands +Date: Wed Jul 31 23:19:03 2024 +0200 - upstream: correct section numbers; from Ed Maste + assert that SCRATCH_DIR is a writable directory - OpenBSD-Commit-ID: e289576ee5651528404cb2fb68945556052cf83f + SSH-Copy-ID-Upstream: ecb2b9d10883b9a16df56c83896c9bb47a80cde2 -commit 430ef864645cff83a4022f5b050174c840e275da -Author: djm@openbsd.org -Date: Mon Dec 18 15:58:56 2023 +0000 +commit abcc460a2af46f0d812f8433d97a8eae1d80724c +Author: Philip Hands +Date: Wed Jul 31 23:17:54 2024 +0200 - upstream: match flag type (s/int/u_int) + quote to avoid potential for word splitting - OpenBSD-Commit-ID: 9422289747c35ccb7b31d0e1888ccd5e74ad566a + SSH-Copy-ID-Upstream: f379adbe06ac2ef1daf0f130752234c7f8b97e3c -commit 1036d77b34a5fa15e56f516b81b9928006848cbd -Author: Damien Miller -Date: Fri Dec 22 17:56:26 2023 +1100 +commit b3f91411fd1473605f74c40c1a91a024c7171e27 +Author: Philip Hands +Date: Wed Jul 31 23:15:11 2024 +0200 - better detection of broken -fzero-call-used-regs + ensure ERROR output goes to STDERR - gcc 13.2.0 on ppc64le refuses to compile some function, including - cipher.c:compression_alg_list() with an error: + SSH-Copy-ID-Upstream: ac394b05eead3b91feb7c2ae4129a3e9b892f1e2 + +commit 674b8f30f0dbacd787eb1e4e7e1ece34b5543d8f +Author: Philip Hands +Date: Thu Aug 1 14:03:06 2024 +0200 + + avoid extra space when no arg given to -i option - > sorry, unimplemented: argument ‘used’ is not supportedcw - > for ‘-fzero-call-used-regs’ on this target + SSH-Copy-ID-Upstream: feca9e67e6e37c5653445d1c733569d7abb1770e + +commit 0efa0e1c41427c0c6ba839a18c72c1afcd7b7cc0 +Author: Philip Hands +Date: Wed Jul 31 23:28:36 2024 +0200 + + put the -i before -[pP] (matching man pages) - This extends the autoconf will-it-work test with a similarly- - structured function that seems to catch this. + The man pages (ssh, sftp & ssh-copy-id) all list -i before the port + setting, so make the output match that order, which also seems more + natural with the port being next to the server. - Spotted/tested by Colin Watson; bz3645 + SSH-Copy-ID-Upstream: 34d5d614172c78f9a42249466c4b81975b8883a1 -commit 8241b9c0529228b4b86d88b1a6076fb9f97e4a99 +commit 87831345e9745f2d13bd7a4a7972809f6788f331 +Author: Shreyas Mahangade +Date: Mon Jul 29 15:26:05 2024 +0000 + + Minor space issue fixed + + SSH-Copy-ID-Upstream: 335e44d7be78b03962a54c3a5c99a2ff45294a54 + +commit 2f3010f4736b4b3f5c10a4be97a24e90ff04c5e7 +Author: Shreyas Mahangade +Date: Mon Jul 29 16:55:28 2024 +0530 + + Show identity file in 'ssh' command + + - Previously no identity file is shown in "ssh" command output on the line "Now try logging into the..." + - This commit makes sure whenever "ssh-copy-id" with "-i" is invoked, it also reflects in "ssh" command + + SSH-Copy-ID-Upstream: 58e022ec26cb2315eb3be581d01e0ba787082428 + +commit a13856374b894397a7682b32257ed0bf67cfede9 Author: Damien Miller -Date: Tue Dec 19 01:59:50 2023 +1100 +Date: Fri Aug 16 08:30:20 2024 +1000 - crank versions + more OPENSSL_HAS_ECC -commit 2f2c65cb5f1518a9c556d3e8efa27ea0ca305c6b +commit 4da2a1a7f648979bea6eaf3b17f5f250faed4afc Author: Damien Miller -Date: Tue Dec 19 01:59:06 2023 +1100 +Date: Thu Aug 15 23:35:54 2024 +1000 - depend + fix merge botch that broke !OPENSSL_HAS_ECC -commit e48cdee8e19059203b1aeeabec2350b8375fa61f -Author: djm@openbsd.org -Date: Mon Dec 18 14:50:08 2023 +0000 +commit 2c53d2f32b8e3992b61682c909ae5bc5122b6e5d +Author: Damien Miller +Date: Thu Aug 15 15:09:45 2024 +1000 - upstream: regress test for agent PKCS#11-backed certificates + missed OPENSSL_HAS_ECC case + +commit 342dd7a219f39119b8b686b5aaa99c8e15ede368 +Author: Damien Miller +Date: Thu Aug 15 15:06:55 2024 +1000 + + retire testing aginst older LibreSSL versions - OpenBSD-Regress-ID: 38f681777cb944a8cc3bf9d0ad62959a16764df9 + libressl prior to 3.4.x lack support for the EVP_DigestSign and + EVP_DigestVerify APIs that we need now that sshkey is converted + to EVP_PKEY. + + If someone makes a good case for why we should support these versions + then we could bring back support with wrappers. -commit 2f512f862df1d5f456f82a0334c9e8cc7208a2a1 +commit a7c6ea8eebe0f179141ec5dbf0c9e5354417930f +Author: Damien Miller +Date: Thu Aug 15 12:44:17 2024 +1000 + + sync TEST_MALLOC_OPTIONS for OpenBSD + +commit 60c2cf22e8f64f35d8b1175e4671257313f2e4d3 +Author: Damien Miller +Date: Thu Aug 15 12:43:47 2024 +1000 + + remove gratuitious difference from OpenBSD + +commit 339c4fc60a6250429d41fa8713f783d82aad4551 Author: djm@openbsd.org -Date: Mon Dec 18 14:49:39 2023 +0000 +Date: Thu Aug 15 00:52:23 2024 +0000 - upstream: regress test for constrained PKCS#11 keys + upstream: adapt to EVP_PKEY conversion - OpenBSD-Regress-ID: b2f26ae95d609d12257b43aef7cd7714c82618ff + OpenBSD-Regress-ID: 0e2d4efb0ed0e392e23cd8fda183fe56531ac446 -commit cdddd66412ca5920ed4d3ebbfa6ace12dbd9b82f +commit 63a94f99b9d7c8a48182a40192e45879d1ba8791 Author: djm@openbsd.org -Date: Mon Dec 18 14:48:44 2023 +0000 +Date: Fri Jul 19 04:33:36 2024 +0000 - upstream: openssh-9.6 + upstream: test transfers in mux proxy mode too - OpenBSD-Commit-ID: 21759837cf0e0092d9a2079f8fb562071c11016b + OpenBSD-Regress-ID: 2edfc980628cfef3550649cab8d69fa23b5cd6c4 -commit 6d51feab157cedf1e7ef5b3f8781ca8ff9c4ab1b +commit 7bdfc20516e288b58c8c847958059c7b141eeff9 Author: djm@openbsd.org -Date: Mon Dec 18 14:48:08 2023 +0000 +Date: Thu Aug 15 00:51:51 2024 +0000 - upstream: ssh-agent: record failed session-bind attempts + upstream: Convert RSA and ECDSA key to the libcrypto EVP_PKEY API. - Record failed attempts to session-bind a connection and refuse signing - operations on that connection henceforth. + DSA remains unconverted as it will be removed within six months. - Prevents a future situation where we add a new hostkey type that is not - recognised by an older ssh-agent, that consequently causes session-bind - to fail (this situation is only likely to arise when people mix ssh(1) - and ssh-agent(1) of different versions on the same host). Previously, - after such a failure the agent socket would be considered unbound and - not subject to restriction. + Based on patches originally from Dmitry Belyavskiy, but significantly + reworked based on feedback from Bob Beck, Joel Sing and especially + Theo Buehler (apologies to anyone I've missed). - Spotted by Jann Horn + ok tb@ - OpenBSD-Commit-ID: b0fdd023e920aa4831413f640de4c5307b53552e + OpenBSD-Commit-ID: d098744e89f1dc7e5952a6817bef234eced648b5 -commit 7ef3787c84b6b524501211b11a26c742f829af1a -Author: djm@openbsd.org -Date: Mon Dec 18 14:47:44 2023 +0000 +commit 0af06e2c5b898992a18c74333e75a0136506acc6 +Author: tobias@openbsd.org +Date: Wed Aug 14 15:42:18 2024 +0000 - upstream: ban user/hostnames with most shell metacharacters - - This makes ssh(1) refuse user or host names provided on the - commandline that contain most shell metacharacters. - - Some programs that invoke ssh(1) using untrusted data do not filter - metacharacters in arguments they supply. This could create - interactions with user-specified ProxyCommand and other directives - that allow shell injection attacks to occur. + upstream: Reorder calloc arguments - It's a mistake to invoke ssh(1) with arbitrary untrusted arguments, - but getting this stuff right can be tricky, so this should prevent - most obvious ways of creating risky situations. It however is not - and cannot be perfect: ssh(1) has no practical way of interpreting - what shell quoting rules are in use and how they interact with the - user's specified ProxyCommand. + The first argument should be the amount, the second argument should be the + element size. Fixing this also silences some gcc compiler warnings for + portable. - To allow configurations that use strange user or hostnames to - continue to work, this strictness is applied only to names coming - from the commandline. Names specified using User or Hostname - directives in ssh_config(5) are not affected. + Spotted with Benny Baumann (BenBE at geshi dot org). - feedback/ok millert@ markus@ dtucker@ deraadt@ + ok djm@ - OpenBSD-Commit-ID: 3b487348b5964f3e77b6b4d3da4c3b439e94b2d9 + OpenBSD-Commit-ID: 711ad6f7bd7fb48bf52208f2cf9f108cddb6d41a -commit 0cb50eefdd29f0fec31d0e71cc4b004a5f704e67 -Author: djm@openbsd.org -Date: Mon Dec 18 14:47:20 2023 +0000 +commit 56ce0aa3c6cf28d9fcbce3207457abeac91b5050 +Author: tobias@openbsd.org +Date: Wed Aug 14 15:40:30 2024 +0000 - upstream: stricter handling of channel window limits - - This makes ssh/sshd more strict in handling non-compliant peers that - send more data than the advertised channel window allows. Previously - the additional data would be silently discarded. This change will - cause ssh/sshd to terminate the connection if the channel window is - exceeded by more than a small grace allowance. + upstream: Extend sshbuf validation - ok markus@ + Multiple sshbuf structs can be linked through a parent/child relationship. + Make sure that a single sshbuf cannot be its own parent. If this would ever + happen, it would result in reference counting issues. - OpenBSD-Commit-ID: 811e21b41831eba3dd7f67b3d409a438f20d3037 - -commit 4448a2938abc76e6bd33ba09b2ec17a216dfb491 -Author: djm@openbsd.org -Date: Mon Dec 18 14:46:56 2023 +0000 - - upstream: Make it possible to load certs from PKCS#11 tokens + This is a cheap way of testing this with very little overhead. It does not + detect A->B->A linkages though for performance reason and the fact that it + takes a programming error for this to occur anyway. - Adds a protocol extension to allow grafting certificates supplied by - ssh-add to keys loaded from PKCS#11 tokens in the agent. + Authored with Benny Baumann (BenBE at geshi dot org). - feedback/ok markus@ + ok djm@ - OpenBSD-Commit-ID: bb5433cd28ede2bc910996eb3c0b53e20f86037f + OpenBSD-Commit-ID: fb3fa9ee2cad3c7e842ebadfd7f5db220c4aaf16 -commit 881d9c6af9da4257c69c327c4e2f1508b2fa754b -Author: djm@openbsd.org -Date: Mon Dec 18 14:46:12 2023 +0000 +commit fc48ddf6998188517af42dce807e2088b6a0c0be +Author: tobias@openbsd.org +Date: Wed Aug 14 15:37:11 2024 +0000 - upstream: apply destination constraints to all p11 keys + upstream: Use freezero for better readability - Previously applied only to the first key returned from each token. + It has the same meaning as the current pair of calling explicit_bzero + and free. Spotted with Benny Baumann (BenBE at geshi dot org). - ok markus@ + ok djm@ - OpenBSD-Commit-ID: 36df3afb8eb94eec6b2541f063d0d164ef8b488d + OpenBSD-Commit-ID: 939fbe9ccf52d0d48c5fa53694d6f3bb9927970c -commit a7ed931caeb68947d30af8a795f4108b6efad761 -Author: djm@openbsd.org -Date: Mon Dec 18 14:45:49 2023 +0000 +commit 1ff6907ec26dac6ac59fe9fe232899a63b4c14d8 +Author: tobias@openbsd.org +Date: Wed Aug 14 15:35:23 2024 +0000 - upstream: add "ext-info-in-auth@openssh.com" extension - - This adds another transport protocol extension to allow a sshd to send - SSH2_MSG_EXT_INFO during user authentication, after the server has - learned the username that is being logged in to. + upstream: Fix typo in comment - This lets sshd to update the acceptable signature algoritms for public - key authentication, and allows these to be varied via sshd_config(5) - "Match" directives, which are evaluated after the server learns the - username being authenticated. + Spotted with Benny Baumann (BenBE at geshi dot org). - Full details in the PROTOCOL file + ok djm@ - OpenBSD-Commit-ID: 1de7da7f2b6c32a46043d75fcd49b0cbb7db7779 + OpenBSD-Commit-ID: 829160ac8ef3ad3409695ce3a3ade835061cae57 -commit 1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5 -Author: djm@openbsd.org -Date: Mon Dec 18 14:45:17 2023 +0000 +commit 487faaed8f3bb9ffb19e8f807a3da72895b16421 +Author: dlg@openbsd.org +Date: Wed Jul 31 12:00:18 2024 +0000 - upstream: implement "strict key exchange" in ssh and sshd - - This adds a protocol extension to improve the integrity of the SSH - transport protocol, particular in and around the initial key exchange - (KEX) phase. + upstream: add a random amount of time (up to 4 seconds) to the - Full details of the extension are in the PROTOCOL file. + grace login time. - with markus@ + ok deraadt@ djm@ - OpenBSD-Commit-ID: 2a66ac962f0a630d7945fee54004ed9e9c439f14 + OpenBSD-Commit-ID: abd3c57aaa5861517529b322df79b6be35ee67f4 -commit 59d691b886c79e70b1d1c4ab744e81fd176222fd -Author: Damien Miller -Date: Mon Dec 18 14:49:11 2023 +1100 +commit 2865f5b7520bed3e74fbbb5f8d7a44193d7a4314 +Author: naddy@openbsd.org +Date: Fri Jul 26 15:24:49 2024 +0000 - better detection of broken -fzero-call-used-regs + upstream: document the reduced logingrace penalty - Use OSSH_CHECK_CFLAG_LINK() for detection of these flags and extend - test program to exercise varargs, which seems to catch more stuff. + OpenBSD-Commit-ID: 9b63e0e3599d524ddc10edc4f978081382c3548b + +commit 1ec0a64c5dc57b8a2053a93b5ef0d02ff8598e5c +Author: Darren Tucker +Date: Sun Jul 28 21:26:51 2024 +1000 + + Explicitly install libssl-devel cygwin. - ok dtucker@ + Should fix CI tests for cygwin default config. -commit aa7b21708511a6d4aed3839fc9f6e82e849dd4a1 +commit 0bf6e5bb750b66b25c20a1c5a471f91850de3748 Author: djm@openbsd.org -Date: Wed Dec 13 03:28:19 2023 +0000 +Date: Thu Jul 25 23:44:01 2024 +0000 - upstream: when invoking KnownHostsCommand to determine the order of + upstream: reduce logingrace penalty. - host key algorithms to request, ensure that the hostname passed to the - command is decorated with the port number for ports other than 22. - - This matches the behaviour of KnownHostsCommand when invoked to look - up the actual host key. + A single forgotton login that times out should be below the penalty + threshold. - bz3643, ok dtucker@ + ok deraadt/claudio - OpenBSD-Commit-ID: 5cfabc0b7c6c7ab473666df314f377b1f15420b1 + OpenBSD-Commit-ID: cee1f7d17597c97bff8e5092af5d136fdb08f81d -commit 4086bd6652c0badccc020218a62190a7798fb72c -Author: markus@openbsd.org -Date: Fri Dec 8 09:18:39 2023 +0000 +commit 29fb6f6d46b67770084b4f12bcf8a01bd535041b +Author: djm@openbsd.org +Date: Thu Jul 25 22:40:08 2024 +0000 - upstream: prevent leak in sshsig_match_principals; ok djm@ + upstream: Fix proxy multiplexing (-O proxy) bug - OpenBSD-Commit-ID: 594f61ad4819ff5c72dfe99ba666a17f0e1030ae + If a mux started with ControlPersist then later has a forwarding added using + mux proxy connection and the forwarding was used, then when the mux proxy + session terminates, the mux master process will send a channel close to the + server with a bad channel ID and crash the connection. + + This was caused by my stupidly reusing c->remote_id for mux channel + associations when I should have just added another member to struct channel. + + ok markus@ + + OpenBSD-Commit-ID: c9f474e0124e3fe456c5e43749b97d75e65b82b2 -commit 19d3ee2f3adf7d9a606ff015c1e153744702c4c9 +commit 53d1d307438517805989c7d5616d752739a97e03 Author: djm@openbsd.org -Date: Wed Dec 6 21:06:48 2023 +0000 +Date: Thu Jul 18 01:47:27 2024 +0000 - upstream: short circuit debug log processing early if we're not going + upstream: mention mux proxy mode - to log anything. From Kobe Housen - - OpenBSD-Commit-ID: 2bcddd695872a1bef137cfff7823044dcded90ea + OpenBSD-Commit-ID: fd77a77779f06d316a314e4540dc57c93fc3369a -commit 947affad4831df015c498c00c6351ea6f13895d5 -Author: Darren Tucker -Date: Mon Nov 27 09:37:28 2023 +1100 +commit a9b90859d252c2f5a24142f985d38610ac74685f +Author: jsg@openbsd.org +Date: Sun Jul 14 10:19:23 2024 +0000 - Add tests for OpenSSL 3.2.0 and 3.2 stable branch. + upstream: fix double word; ok dtucker@ + + OpenBSD-Commit-ID: e6aff005914fa350b896d2be030be3d3b56ec0e8 -commit 747dce36206675ca6b885010a835733df469351b +commit b05fda224bbcd2f641254534ed2175c42487f3c8 Author: Darren Tucker -Date: Sat Nov 25 09:03:38 2023 +1100 +Date: Thu Jul 25 17:59:35 2024 +1000 - Use non-zero arg in compiler test program. + Check for SA_RESTART before using it. - Now that we're running the test program, passing zero to the test function - can cause divide-by-zero exceptions which might show up in logs. + ok djm@ -commit 3d44a5c56585d1c351dbc006240a591b6da502b1 -Author: dtucker@openbsd.org -Date: Fri Nov 24 00:31:30 2023 +0000 +commit c276672fc0e99f0c4389988d54a84c203ce325b6 +Author: Yuichiro Naito +Date: Wed Sep 1 10:19:32 2021 +0900 - upstream: Plug mem leak of msg when processing a quit message. + Class-imposed login restrictions - Coverity CID#427852, ok djm@ + If the following functions are available, + add an additional check if users are allowed to login imposed by login class. - OpenBSD-Commit-ID: bf85362addbe2134c3d8c4b80f16601fbff823b7 + * auth_hostok(3) + * auth_timeok(3) + + These functions are implemented on FreeBSD. -commit 1d7f9b6e297877bd00973e6dc5c0642dbefc3b5f -Author: dtucker@openbsd.org -Date: Thu Nov 23 03:37:05 2023 +0000 +commit 7717b9e9155209916cc6b4b4b54f4e8fa578e889 +Author: djm@openbsd.org +Date: Wed Jul 10 21:58:34 2024 +0000 - upstream: Include existing mux path in debug message. + upstream: correct keyword; from Yatao Su via GHPR509 - OpenBSD-Commit-ID: 1c3641be10c2f4fbad2a1b088a441d072e18bf16 + OpenBSD-Commit-ID: 81c778c76dea7ef407603caa157eb0c381c52ad2 -commit f29934066bd0e561a2e516b7e584fb92d2eedee0 -Author: Darren Tucker -Date: Thu Nov 23 19:41:27 2023 +1100 +commit f2b78bb8f149d6b4d1f62c21aa1f06995dccf4ce +Author: djm@openbsd.org +Date: Mon Jul 8 03:04:34 2024 +0000 - Add an Ubuntu 22.04 test VM. + upstream: don't need return at end of void function - This is the same version as Github's runners so most of the testing on - it is over there, but having a local VM makes debugging much easier. + OpenBSD-Commit-ID: 42d322d37f13aa075ae7b1ad9eef591e20b89717 -commit a93284a780cd3972afe5f89086b75d564ba157f3 -Author: Darren Tucker -Date: Thu Nov 23 19:36:22 2023 +1100 +commit a395d37a813c0177cb5bfc4bebf5a52badb73cf0 +Author: djm@openbsd.org +Date: Thu Jul 4 22:53:59 2024 +0000 - Add gcc-12 -Werror test on Ubuntu 22.04. + upstream: fix grammar: "a pattern lists" -> "one or more pattern - Explictly specify gcc-11 on Ubuntu 22.04 (it's the system compiler). + lists" + + OpenBSD-Commit-ID: f3c844763398faa9800687e8ff6621225498202a -commit 670f5a647e98b6fd95ad64f789f87ee3274b481b +commit 8b664df75966e5aed8dabea00b8838303d3488b8 Author: Darren Tucker -Date: Thu Nov 23 19:34:57 2023 +1100 +Date: Sun Jul 7 18:46:19 2024 +1000 - Check return value from write to prevent warning. + Cast to sockaddr * in systemd interface. - ... and since we're testing for flags with -Werror, this caused - configure to mis-detect compiler flags. + Fixes build with musl libx. bz#3707. -commit cea007d691cfedfa07a5b8599f97ce0511f53fc9 +commit 30c8c81da2169e78357d08dbb0ddd823b60e93bc Author: Darren Tucker -Date: Wed Nov 22 21:18:55 2023 +1100 +Date: Thu Jul 4 20:12:26 2024 +1000 - Run compiler test program when compiling natively. - - ok djm@ + Add 9.8 branch to ci-status page. -commit ee0d305828f13536c0a416bbf9c3e81039d9ea55 -Author: Darren Tucker -Date: Wed Nov 22 21:18:07 2023 +1100 +commit ee6b9e661633fcefd29dba0c811cecbc4d027f6f +Author: Samuel Thibault +Date: Tue Mar 26 22:15:08 2024 +0100 - Factor out compiler test program into a macro. + Fix detection of setres*id on GNU/Hurd - ok djm@ + Like Linux, proper _SOURCE macros need to be set to get declarations of + various standard functions, notably setres*id. Now that Debian is using + -Werror=implicit-function-declaration this is really required. While at + it, define other _SOURCE macros like on GNU/Linux, since GNU/Hurd uses + the same glibc. -commit de304c76316b029df460673725a9104224b9959b -Author: Darren Tucker -Date: Wed Nov 22 08:55:36 2023 +1100 +commit fa41f6592ff1b6ead4a652ac75af31eabb05b912 +Author: Damien Miller +Date: Mon Jul 1 14:33:26 2024 +1000 - Add fbsd14 VM to test pool. + version numbers -commit 99a2df5e1994cdcb44ba2187b5f34d0e9190be91 -Author: Darren Tucker -Date: Tue Nov 21 16:19:29 2023 +1100 +commit bfebb8a5130a792c5356bd06e1ddef72a0a0449f +Author: djm@openbsd.org +Date: Mon Jul 1 04:31:59 2024 +0000 - Expand -fzero-call-used-regs test to cover gcc 11. + upstream: openssh-9.8 - It turns out that gcc also has some problems with -fzero-call-used-regs, - at least v11 on mips. Previously the test in OSSH_CHECK_CFLAG_COMPILE - was sufficient to catch it with "=all", but not sufficient for "=used". - Expand the testcase and include it in the other tests for good measure. - See bz#3629. ok djm@. + OpenBSD-Commit-ID: 5f8b89e38a4c5f7c6d52ffa19f796d49f36fab19 -commit ff220d4010717f7bfbbc02a2400666fb9d24f250 -Author: Darren Tucker -Date: Tue Nov 21 14:04:34 2023 +1100 +commit 146c420d29d055cc75c8606327a1cf8439fe3a08 +Author: djm@openbsd.org +Date: Mon Jul 1 04:31:17 2024 +0000 - Stop using -fzero-call-used-regs=all + upstream: when sending ObscureKeystrokeTiming chaff packets, we - ... since it seems to be problematic with several different versions of - clang. Only use -fzero-call-used-regs=used which is less - problematic, except with Apple's clang where we don't use it at all. - bz#3629, ok djm@ - -commit 2a19e02f36b16f0f6cc915f7d1e60ead5e36303b -Author: Darren Tucker -Date: Tue Nov 21 14:02:18 2023 +1100 - - Allow for vendor prefix on clang version numbers. + can't rely on channel_did_enqueue to tell that there is data to send. This + flag indicates that the channels code enqueued a packet on _this_ ppoll() + iteration, not that data was enqueued in _any_ ppoll() iteration in the + timeslice. ok markus@ - Correctly detects the version of OpenBSD's native clang, as well as - Apple's. Spotted tb@, ok djm@. + OpenBSD-Commit-ID: 009b74fd2769b36b5284a0188ade182f00564136 -commit c52db0114826d73eff6cdbf205e9c1fa4f7ca6c6 +commit 637e4dfea4ed81264e264b6200172ce319c64ead Author: djm@openbsd.org -Date: Mon Nov 20 02:50:00 2023 +0000 +Date: Mon Jul 1 03:10:19 2024 +0000 - upstream: set errno=EAFNOSUPPORT when filtering addresses that don't + upstream: use "lcd" to change directory before "lls" rather then "cd", - match AddressFamily; yields slightly better error message if no address - matches. bz#3526 + since the directory we're trying to list is local. Spotted by Corinna + Vinschen - OpenBSD-Commit-ID: 29cea900ddd8b04a4d1968da5c4a893be2ebd9e6 + OpenBSD-Regress-ID: 821feca4a4bebe491944e624c8f7f2990b891415 -commit 26f3f3bbc69196d908cad6558c8c7dc5beb8d74a +commit c8cfe258cee0b8466ea84597bf15e1fcff3bc328 Author: djm@openbsd.org -Date: Wed Nov 15 23:03:38 2023 +0000 +Date: Thu Jun 27 23:01:15 2024 +0000 - upstream: when connecting via socket (the default case), filter - - addresses by AddressFamily if one was specified. Fixes the case where, if - CanonicalizeHostname is enabled, ssh may ignore AddressFamily. bz5326; ok - dtucker + upstream: delete obsolete comment - OpenBSD-Commit-ID: 6c7d7751f6cd055126b2b268a7b64dcafa447439 + OpenBSD-Commit-ID: 5fb04f298ed155053f3fbfdf0c6fe7cdf84bbfa2 -commit 050c335c8da43741ed0df2570ebfbd5d1dfd0a31 +commit 94b9d37100f6fa536aaa1d1a0e4926fe44fbf04d Author: djm@openbsd.org -Date: Wed Nov 15 22:51:49 2023 +0000 +Date: Thu Jun 27 22:36:44 2024 +0000 - upstream: when deciding whether to enable keystroke timing - - obfuscation, only consider enabling it when a channel with a tty is open. - - Avoids turning on the obfucation when X11 forwarding only is in use, - which slows it right down. Reported by Roger Marsh + upstream: retire unused API - OpenBSD-Commit-ID: c292f738db410f729190f92de100c39ec931a4f1 + OpenBSD-Commit-ID: 3e30d7b0615e2707f6bbe70f61b1c2f72f78161b -commit 676377ce67807a24e08a54cd60ec832946cc6cae -Author: tobhe@openbsd.org -Date: Mon Nov 13 09:18:19 2023 +0000 +commit 268c3a7f5783e731ed60f4e28da66ee3743581d3 +Author: jmc@openbsd.org +Date: Thu Jun 27 21:02:16 2024 +0000 - upstream: Make sure sftp_get_limits() only returns 0 if 'limits' + upstream: ssl(8) no longer contains a HISTORY section; - was initialized. This fixes a potential uninitialized use of 'limits' in - sftp_init() if sftp_get_limits() returned early because of an unexpected - message type. + OpenBSD-Commit-ID: 83b7ff34433d79595e9c2a5d2a561a6660251245 + +commit 12b6cc09ce6c430681f03af2a8069e37a664690b +Author: djm@openbsd.org +Date: Wed Jun 26 23:47:46 2024 +0000 + + upstream: move child process waitpid() loop out of SIGCHLD handler; - ok djm@ + ok deraadt - OpenBSD-Commit-ID: 1c177d7c3becc1d71bc8763eecf61873a1d3884c + OpenBSD-Commit-ID: 65815a39564e431414aed7c5ace8076f4e9ca741 -commit 64e0600f23c6dec36c3875392ac95b8a9100c2d6 -Author: Darren Tucker -Date: Mon Nov 13 20:03:31 2023 +1100 +commit d6bcd13297c2ab8b528df5a6898f994734849031 +Author: deraadt@openbsd.org +Date: Wed Jun 26 23:16:52 2024 +0000 - Test current releases of LibreSSL and OpenSSL. + upstream: Instead of using possibly complex ssh_signal(), write all - Retire some of the older releases. + the parts of the grace_alarm_handler() using the exact things allowed by the + signal-safe rules. This is a good rule of thumb: Handlers should be written + to either set a global volatile sig_atomic_t inspected from outside, and/or + directly perform only safe operations listed in our sigaction(2) manual page. + ok djm markus + + OpenBSD-Commit-ID: 14168ae8368aab76e4ed79e17a667cb46f404ecd -commit c8ed7cc545879ac15f6ce428be4b29c35598bb2a -Author: dtucker@openbsd.org -Date: Wed Nov 1 02:08:38 2023 +0000 +commit b8793e2b0851f7d71b97554fa5260b23796d6277 +Author: deraadt@openbsd.org +Date: Wed Jun 26 23:14:14 2024 +0000 - upstream: Specify ssh binary to use + upstream: save_errno wrappers inside two small signal handlers that - ... instead of relying on installed one. Fixes test failures in -portable - when running tests prior to installation. + perform system calls, for systems with libc that do perform libc sigtramps. + ok djm markus - OpenBSD-Regress-ID: b6d6ba71c23209c616efc805a60d9a445d53a685 + OpenBSD-Commit-ID: 7749b56419a7c9dcfe4c6c04811e429813346c62 -commit e9fc2c48121cada1b4dcc5dadea5d447fe0093c3 -Author: Darren Tucker -Date: Wed Nov 1 13:11:31 2023 +1100 +commit f23e9332c4c8df37465c4a4f38275ea98980ed7e +Author: jmc@openbsd.org +Date: Mon Jun 24 06:59:39 2024 +0000 - Put long-running test targets on hipri runners. + upstream: - uppercase start of sentence - correct sentence grammar - Some of the selfhosted test targets take a long time to run for various - reasons, so label them for "libvirt-hipri" runners so that they can - start immediately. This should reduce the time to complete all tests. + ok djm + + OpenBSD-Commit-ID: 1ec4b0fdb633a43667f2c8fff1d600bd647dde25 -commit 7ddf27668f0e21233f08c0ab2fe9ee3fdd6ab1e2 +commit 1839e3eb71a759aa795602c1e4196300f4ac2615 Author: djm@openbsd.org -Date: Wed Nov 1 00:29:46 2023 +0000 +Date: Mon Jun 24 04:05:11 2024 +0000 - upstream: add some tests of forced commands overriding Subsystem - - directives + upstream: mention SshdSessionPath option - OpenBSD-Regress-ID: eb48610282f6371672bdf2a8b5d2aa33cfbd322b + OpenBSD-Commit-ID: c29734d36c21003973b15c1c9965c35f36cef30c -commit fb06f9b5a065dfbbef5916fc4accc03c0bf026dd +commit 603193e32aef5db7d60c58066d5de89806e79312 +Author: Darren Tucker +Date: Thu Jun 20 18:45:14 2024 +1000 + + Rerun upstream tests on .sh file changes too. + +commit dbbf9337c19381786a8e5a8a49152fe6b80c780d Author: dtucker@openbsd.org -Date: Tue Oct 31 04:15:40 2023 +0000 +Date: Thu Jun 20 08:23:18 2024 +0000 - upstream: Don't try to use sudo inside sshd log wrapper. + upstream: Work around dbclient cipher/mac query bug. - We still need to check if we're using sudo since we don't want to chown - unecessarily, as on some platforms this causes an error which pollutes - stderr. We also don't want to unnecessarily invoke sudo, since it's - running in the context of the proxycommand, on *other* platforms it - may not be able to authenticate, and if we're using SUDO then it should - already be privileged. + Unlike earlier versions, recent Dropbear (at least v2024.85) requires + a host arg when querying supported ciphers and macs via "-c/-m + help". Earlier versions accept but do not require it, so always + provide it. If these queries fail, skip the test with a warning. - OpenBSD-Regress-ID: 70d58df7503db699de579a9479300e5f3735f4ee + OpenBSD-Regress-ID: 98eb863a3f0363416922efb273885e6b3c7f68d4 -commit fc3cc33e88c242c704781c6c48087838f1dcfa2a +commit 8de2c8cebc46bbdb94b7a2c120fcadfb66a3cccc Author: dtucker@openbsd.org -Date: Tue Oct 31 02:58:45 2023 +0000 +Date: Thu Jun 20 08:18:34 2024 +0000 - upstream: Only try to chmod logfile if we have sudo. If we don't have + upstream: Remove dropbear key types not supported - sudo then we won't need to chmod. + by current OpenSSH. Allows subsequent test runs to work if OpenSSH is + rebuilt w/out OpenSSL. - OpenBSD-Regress-ID: dbad2f5ece839658ef8af3376cb1fb1cabe2e324 + OpenBSD-Regress-ID: e0129eb2b1d31771105903a8055216fbba20a770 -commit 3a506598fddd3f18f9095af3fe917f24cbdd32e0 +commit e9b6471c59b21e5d9ef1b3832d4bf727338add85 Author: djm@openbsd.org -Date: Mon Oct 30 23:00:25 2023 +0000 +Date: Thu Jun 20 00:18:05 2024 +0000 - upstream: move PKCS#11 setup code to test-exec.sh so it can be reused - - elsewhere + upstream: stricter check for overfull tables in penalty record path - OpenBSD-Regress-ID: 1d29e6be40f994419795d9e660a8d07f538f0acb + OpenBSD-Commit-ID: 7df01e648a0723418c554e64a9f2b6d38db060a6 -commit f82fa227a52661c37404a6d33bbabf14fed05db0 +commit d9336d344eb2a1e898c5e66147b3f108c7214694 Author: djm@openbsd.org -Date: Mon Oct 30 17:32:00 2023 +0000 +Date: Wed Jun 19 23:24:47 2024 +0000 - upstream: tidy and refactor PKCS#11 setup code - - Replace the use of a perl script to delete the controlling TTY with a - SSH_ASKPASS script to directly load the PIN. + upstream: put back reaping of preauth child process when writes - Move PKCS#11 setup code to functions in anticipation of it being used - elsewhere in additional tests. + from the monitor fail. Not sure how this got lost in the avalanche of + patches. - Reduce stdout spam + OpenBSD-Commit-ID: eb7eb36371e1ac01050b32b70fb2b3e5d98e72f5 + +commit 579d9adb70ec0206a788eb5c63804c31a67e9310 +Author: naddy@openbsd.org +Date: Mon Jun 17 13:50:18 2024 +0000 + + upstream: remove one more mention of DSA - OpenBSD-Regress-ID: 07705c31de30bab9601a95daf1ee6bef821dd262 + OpenBSD-Commit-ID: 8515f55a15f02836ba657df341415f63c60526ca -commit 3cf698c6d4ffa9be1da55672a3519e2135a6366a +commit 7089b5f8436ef0b8d3d3ad9ce01045fb9e7aab15 Author: Darren Tucker -Date: Mon Oct 30 21:35:03 2023 +1100 +Date: Wed Jun 19 23:09:05 2024 +1000 - Add obsd74 test VM and retire obsd69 and obsd70. + Move -f to the place needed to restart sshd. -commit 3e21d58a09894acb38dc69ed615d101131f473d0 +commit d5f83cfd852b14a25f347f082ab539a9454702ad Author: Darren Tucker -Date: Mon Oct 30 18:34:12 2023 +1100 +Date: Wed Jun 19 21:04:01 2024 +1000 - Add OpenSSL 3.3.0 as a known dev version. + Need to supply "-f" to restart sshd. -commit 917ba181c2cbdb250a443589ec732aa36fd51ffa -Author: Darren Tucker -Date: Mon Oct 30 13:32:03 2023 +1100 +commit fad34b4ca25c0ef31e5aa841d461b6f21da5b8c1 +Author: dtucker@openbsd.org +Date: Wed Jun 19 10:15:51 2024 +0000 - Restore nopasswd sudo rule on Mac OS X. + upstream: Provide defaults for ciphers and macs - This seems to be missing from some (but not all) github runners, so - restore it if it seems to be missing. - -commit c5698abad6d4ec98ca20bcaaabaeacd5e1ec3f4f -Author: Darren Tucker -Date: Mon Oct 30 13:26:52 2023 +1100 - - Don't exit early when setting up on Mac OS X. + if querying for them fails since on some versions of Dropbear (at least + v2024.85) "-m help" doesn't seem to work. Enable all supported pubkey + algorithms in the server. - We probably need some of the other bits in there (specifically, setting - the perms on the home directory) so make it less of a special snowflake. + OpenBSD-Regress-ID: 4f95556a49ee9f621789f25217c367a33d2745ca -commit 1d6a878ceba60b9dc14037dddc8f036070c0065f +commit 5521060e35ada9f957cecdddc06d0524e75409ef Author: dtucker@openbsd.org -Date: Sun Oct 29 06:22:07 2023 +0000 +Date: Wed Jun 19 10:10:46 2024 +0000 - upstream: Only try to chown logfiles that exist to prevent spurious + upstream: Use ed25519 keys for kex tests - errors. + since that's supported by OpenSSH even when built without OpenSSL. + Only test diffie-hellman kex if OpenSSH is compiled with support for it. - OpenBSD-Regress-ID: f1b20a476734e885078c481f1324c9ea03af991e + OpenBSD-Regress-ID: a5d09ef9bbd171f9e4ec73ed0d9eeb49a8878e97 -commit e612376427a66f835e284f6b426d16d7c85301bc -Author: anton@openbsd.org -Date: Thu Oct 26 18:52:45 2023 +0000 +commit dbd3b833f6e3815e58f2dc6e14f61a51bcd4d6bd +Author: dtucker@openbsd.org +Date: Wed Jun 19 10:08:34 2024 +0000 - upstream: make use of bsd.regress.mk in extra and interop targets; ok + upstream: Rework dropbear key setup - dtucker@ + to always generate ed25519 keys, other types only if OpenSSH has support + for the corresponding key type. - OpenBSD-Regress-ID: 7ea21b5f6fc4506165093b2123d88d20ff13a4f0 + OpenBSD-Regress-ID: 8f91f12604cddb9f8d93aa34f3f93a3f6074395d -commit ea0039173957d0edcd6469b9614dcedb44dcb4f9 -Author: dtucker@openbsd.org -Date: Thu Oct 26 12:44:07 2023 +0000 +commit d6218504e11ae9148adf410fc69b0710a052be36 +Author: Darren Tucker +Date: Wed Jun 19 20:20:24 2024 +1000 - upstream: Skip conch interop tests when not enabled instead of fatal. + Restart sshd after installing it for testing. - OpenBSD-Regress-ID: b0abf81c24ac6c21f367233663228ba16fa96a46 + When installing an sshd built without OpenSSL the mismatch between + the running sshd and newly installed sshd-session will cause the + remainder of the test to fail. -commit d220b9ed5494252b26b95f05be118472bc3ab5c0 -Author: dtucker@openbsd.org -Date: Wed Oct 25 05:38:08 2023 +0000 +commit 786a4465b6bb702daf4fb17b7c3bcb42b52f0b46 +Author: Darren Tucker +Date: Tue Jun 18 19:59:59 2024 +1000 - upstream: Import regenerated moduli. + Remove macos-11 runner. - OpenBSD-Commit-ID: 95f5dd6107e8902b87dc5b005ef2b53f1ff378b8 + Github is retiring them soon. -commit a611e4db4009447a0151f31a44e235ca32ed4429 -Author: anton@openbsd.org -Date: Wed Oct 25 08:01:59 2023 +0000 +commit df1c72a55edbebac14363b57de66ac6a147ecc67 +Author: Damien Miller +Date: Wed Jun 19 09:34:34 2024 +1000 - upstream: ssh conch interop tests requires a controlling terminal; - - ok dtucker@ - - OpenBSD-Regress-ID: cbf2701bc347c2f19d907f113779c666f1ecae4a + PAMServiceName may appear in a Match block -commit da951b5e08c167acb5d6e2eec6f146502f5d6ed8 -Author: anton@openbsd.org -Date: Mon Oct 23 11:30:49 2023 +0000 +commit de1c2e70e5a5dc3c8d2fe04b24cc93d8ef6930e7 +Author: dtucker@openbsd.org +Date: Tue Jun 18 08:11:48 2024 +0000 - upstream: Use private key that is allowed by sshd defaults in conch - - interop tests. + upstream: Re-enable ssh-dss tests - ok dtucker@ + ... if ssh is compiled with DSA support - OpenBSD-Regress-ID: 3b7f65c8f409c328bcd4b704f60cb3d31746f045 - -commit 1ca166dbb3c0ce632b98869cd955f69320aa6fe8 -Author: Darren Tucker -Date: Fri Oct 20 20:43:00 2023 +1100 - - Install Dropbear for interop testing. + OpenBSD-Regress-ID: bbfaf8c17f2b50a2d46ac35cb97af99b990c990d -commit f993bb58351c5cb71e61aede63805a34a6d4daea -Author: Darren Tucker -Date: Fri Oct 20 20:39:03 2023 +1100 +commit dabc2c7cf3c141e8e5d5a1a60d6c1d2d2422cf43 +Author: anton@openbsd.org +Date: Tue Jun 18 06:14:27 2024 +0000 - Resync PuTTY and Conch path handling with upstream. + upstream: Stop using DSA in dropbear interop tests. - Now that configure finds these for us we can remove these -portable - specific changes. + OpenBSD-Regress-ID: abfd4457d99d8cc1417fd22ca2c570270f74c1cf -commit ff85becd5f5f06a76efa45d30fb204a3c5e5215c -Author: Darren Tucker -Date: Fri Oct 20 20:35:46 2023 +1100 +commit 761438012710169445acc179e3870c53c862bda0 +Author: Damien Miller +Date: Tue Jun 18 12:29:45 2024 +1000 - Have configure find PuTTY and Conch binaries. - - This will let us remove some -portable specific changes from - test-exec.sh. + missed a bit of DSA in the fuzzer -commit c54a50359b9cecddbf3ffcdc26efcb3cd6071ec1 -Author: dtucker@openbsd.org -Date: Fri Oct 20 07:37:07 2023 +0000 +commit 3f9cc47da588e8de520720e59f98438043fdaf93 +Author: Damien Miller +Date: Tue Jun 18 09:35:53 2024 +1000 - upstream: Allow overriding the locations of the Dropbear binaries - - similar to what we do for the PuTTY ones. - - OpenBSD-Regress-ID: 7de0e00518fb0c8fdc5f243b7f82f523c936049c + DSA support is disabled, so remove from fuzzers -commit fbaa707d455a61d0aef8ae65e02a25bac5351e5c -Author: dtucker@openbsd.org -Date: Fri Oct 20 06:56:45 2023 +0000 +commit 00eb95957dea5484b2c7c043f7d2bbc87301bef2 +Author: djm@openbsd.org +Date: Mon Jun 17 08:30:29 2024 +0000 - upstream: Add interop test with Dropbear. - - Right now this is only dbclient not the Dropbear server since it won't - currently run as a ProxyCommand. + upstream: disable the DSA signature algorithm by default; ok - OpenBSD-Regress-ID: 8cb898c414fcdb252ca6328896b0687acdaee496 - -commit c2003d0dbdcdb61ca336c3f90c5c2b4a09c8e73f -Author: Fabio Pedretti -Date: Mon Oct 16 11:59:53 2023 +0200 - - Update openssl-devel dependency in RPM spec. + markus@ - Since openssh 9.4p1, openssl >= 1.1.1 is required, so - build with --without-openssl elsewhere. - According to https://repology.org/project/openssl/versions - openssl 1.1.1 is available on fedora >= 29 and rhel >= 8. - Successfully build tested, installed and run on rhel 6 - -commit 064e09cd632721c7e6889904e07767443ee23821 -Author: Fabio Pedretti -Date: Mon Oct 16 10:13:06 2023 +0200 - - Remove reference of dropped sshd.pam.old file + (yes, I know this expands to "the Digitial Signature Algorithm + signature algorithm) - The file was removed in openssh 8.8 + OpenBSD-Commit-ID: 961ef594e46dd2dcade8dd5721fa565cee79ffed -commit 62db354b696b378a164b6e478cb6b0171dcb0c3d -Author: dtucker@openbsd.org -Date: Mon Oct 16 08:40:00 2023 +0000 +commit 5603befe11c9464ea26fe77cbacc95a7cc0b1ea7 +Author: djm@openbsd.org +Date: Mon Jun 17 08:28:31 2024 +0000 - upstream: Move declaration of "len" into the block where it's used. + upstream: promote connection-closed messages from verbose to info - This lets us compile Portable with -Werror with when OpenSSL doesn't have - Ed25519 support. + log level; they could be the only record of the connection terminating if the + client doesn't send a SSH2_MSG_DISCONNECT message. ok dtucker@ - OpenBSD-Commit-ID: e02e4b4af351946562a7caee905da60eff16ba29 + OpenBSD-Commit-ID: 0c8bfaf5e9fdff945cee09ac21e641f6c5d65d3c -commit 6eee8c972d5901d10e80634a006b4e346b2c8c19 +commit b00331402fe5c60d577f3ffcc35e49286cdc6b47 Author: Damien Miller -Date: Fri Oct 13 15:15:05 2023 +1100 +Date: Mon Jun 17 17:02:18 2024 +1000 - run t-extra regress tests + propagate PAM crashes to PerSourcePenalties - This exposes the t-extra regress tests (including agent-pkcs11.sh) as - a new extra-tests target in the top level Makefile and runs them by - default. ok dtucker@ + If the PAM subprocess crashes, exit with a crash status that will be + picked up by the sshd(8) listener process where it can be used by + PerSourcePenalties to block the client. This is similar handling to + the privsep preauth process. -commit 637624dbbac13f2bc3c8ec5b15c9d627d07f2935 -Author: Darren Tucker -Date: Thu Oct 12 22:01:23 2023 +1100 +commit 1c207f456ace38987deda047758d13fbf857f948 +Author: Damien Miller +Date: Mon Jun 17 15:06:01 2024 +1000 - Don't use make -j2. + minix doesn't have loopback, so skip penalty tests - While we have 2 cores available on github runners, not using it means - that the most recent log message is the actual failure, rather than - having to search back through the log for it. + pointed out by dtucker@ -commit 971e0cfcfd52ef1d73cf5244074c306a60006e89 -Author: Darren Tucker -Date: Thu Oct 12 16:23:05 2023 +1100 +commit 48443d202eaec52d4d39defdd709a4499a7140c6 +Author: djm@openbsd.org +Date: Sun Jun 16 11:54:49 2024 +0000 - Correct arg order for ED255519 AC_LINK_IFELSE test. + upstream: same treatment for this test + + OpenBSD-Regress-ID: d0cc9efca7833e673ea7b0cb3a679a3acee8d4c7 -commit c616e64688b2a0c1b4daad69b056099be998d121 +commit 45562a95ea11d328c22d97bf39401cd29684fb1f Author: djm@openbsd.org -Date: Thu Oct 12 03:51:08 2023 +0000 +Date: Sun Jun 16 08:18:06 2024 +0000 - upstream: typos and extra debug trace calls + upstream: penalty test is still a bit racy - OpenBSD-Regress-ID: 98a2a6b9333743274359e3c0f0e65cf919a591d1 + OpenBSD-Regress-ID: 90c9ac224db454637baf1ebee5857e007321e824 -commit c49a3fbf10162128c67c59562348de2041188974 +commit 8d0f7eb147ef72d18acb16c0b18672d44941a8ca Author: djm@openbsd.org -Date: Thu Oct 12 03:48:53 2023 +0000 +Date: Sat Jun 15 03:59:10 2024 +0000 - upstream: ensure logs are owned by correct user; feedback/ok + upstream: crank up penalty timeouts so this should work on even the - dtucker@ + slowest of test builders - OpenBSD-Regress-ID: c3297af8f07717f1d400a5d34529962f1a76b5a3 + OpenBSD-Regress-ID: 70bda39c83e3fc9d0f3c1fad4542ed33e173d468 -commit 5ec0ed79ac074c3437b25f6cba8b8cf21c8d4587 +commit 93c75471a1202ab3e29db6938648d4e2602c0475 +Author: jmc@openbsd.org +Date: Fri Jun 14 05:20:34 2024 +0000 + + upstream: sort -q in the options list; + + OpenBSD-Commit-ID: 6839b38378f38f754de638a5e988c13b4164cc7c + +commit dd7807bbe80a93ffb4616f2bd5cf83ad5a5595fb Author: djm@openbsd.org -Date: Thu Oct 12 03:36:32 2023 +0000 +Date: Fri Jun 14 05:01:22 2024 +0000 - upstream: 64 %-expansion keys ought to be enough for anybody; ok + upstream: clarify KEXAlgorithms supported vs available. Inspired by - dtucker (we just hit the previous limit in some cases) + bz3701 from Colin Watson. - OpenBSD-Commit-ID: 84070f8001ec22ff5d669f836b62f206e08c5787 + OpenBSD-Commit-ID: e698e69bea19bd52971d253f2b1094490c4701f7 -commit f59a94e22e46db2c23eddeb871aa9e8d93ab0016 +commit d172ad56df85b68316dbadbedad16761a1265874 Author: djm@openbsd.org -Date: Thu Oct 12 02:48:43 2023 +0000 +Date: Fri Jun 14 05:00:42 2024 +0000 - upstream: don't dereference NULL pointer when hashing jumphost + upstream: ssh-keyscan -q man bits - OpenBSD-Commit-ID: 251c0263e1759a921341c7efe7f1d4c73e1c70f4 + OpenBSD-Commit-ID: ba28d0e1ac609a4c99c453e57e86560c79079db1 -commit 281c79168edcc303abfd5bca983616eaa24c5f32 +commit 092e4ff9ccaacbe035f286feb1b56ed499604743 Author: Damien Miller -Date: Thu Oct 12 13:20:01 2023 +1100 +Date: Fri Jun 14 14:46:35 2024 +1000 - Solaris: prefer PRIV_XPOLICY to PRIV_LIMIT - - If the system support PRIV_XPOLICY and one is set, then don't - modify PRIV_LIMIT. bz2833, patch from Ron Jordan, ok dtucker@ + skip penalty-expire test in valgrind test env -commit 98fc34df837f3a3b79d2a111b96fe8a39adcab55 +commit 2866ad08a9c50d7b67ce9424ca990532b806a21a Author: djm@openbsd.org -Date: Thu Oct 12 02:18:18 2023 +0000 +Date: Fri Jun 14 04:43:11 2024 +0000 - upstream: add %j token that expands to the configured ProxyJump - - hostname (or the empty string if this option is not being used). bz3610, ok - dtucker + upstream: split the PerSourcePenalties test in two: one tests penalty - OpenBSD-Commit-ID: ce9983f7efe6a178db90dc5c1698df025df5e339 - -commit 7f3180be8a85320b5d3221714b40c16e66881249 -Author: djm@openbsd.org -Date: Thu Oct 12 02:15:53 2023 +0000 - - upstream: release GSS OIDs only at end of authentication; bz2982, + enforcement but not penalty expiry, the other tests penalty expiry. - ok dtucker@ + This lets us disable the expiry testing in certain CI test environments. - OpenBSD-Commit-ID: 0daa41e0525ae63cae4483519ecaa37ac485d94c + OpenBSD-Regress-ID: f56811064f3e3cb52ee73a206b8c2a06af1c8791 -commit a612b93de5d86e955bfb6e24278f621118eea500 -Author: djm@openbsd.org -Date: Thu Oct 12 02:12:53 2023 +0000 +commit b2c64bc170d75823622a37cab3ca1804ca87ad16 +Author: Damien Miller +Date: Fri Jun 14 14:19:23 2024 +1000 - upstream: mask SIGINT/TERM/QUIT/HUP before checking quit_pending + add a sshd_config PamServiceName option - and use ppoll() to unmask them in the mainloop. Avoids race condition between - signaling ssh to exit and polling. bz3531; ok dtucker + Allows selecting which PAM service name to use when UsePAM is + enabled. Defaults to "sshd" unless overridden at compile time + by defining SSHD_PAM_SERVICE. - OpenBSD-Commit-ID: 5c14e1aabcddedb95cdf972283d9c0d5083229e7 + bz2102, ok dtucker@ -commit 531b27a006116fe7aff325510aaa576f24844452 +commit 9f032a4dd17bf0ae6066223d82aa5e784285d987 Author: djm@openbsd.org -Date: Wed Oct 11 23:23:58 2023 +0000 +Date: Fri Jun 14 00:26:12 2024 +0000 - upstream: sync usage() with ssh.1; spotted by kn@ + upstream: don't redirect stderr for ssh-keyscan we expect to succeed - OpenBSD-Commit-ID: 191a85639477dcb5fa1616d270d93b7c8d5c1dfd + OpenBSD-Regress-ID: 8878b8eb4e070ed2e343166d3eb86db4a08a216c -commit 64f7ca881b19be754425dca60d1590d306c9d1d0 +commit 1e84d0cf40e94ae3a77d6a7ca8c036d8e3d55a40 Author: djm@openbsd.org -Date: Wed Oct 11 23:14:33 2023 +0000 +Date: Fri Jun 14 00:25:25 2024 +0000 - upstream: ssh -Q does not make sense with other command-line options, + upstream: make host/banner comments go to stderr instead of stdout, - so give it its own line in the manpage + so they are useful as comments without extra shell redirection and so they + don't clutter actual errors on stderr. - OpenBSD-Commit-ID: 00a747f0655c12122bbb77c2796be0013c105361 - -commit a752a6c0e1001f93696d7025f0c867f0376e2ecf -Author: djm@openbsd.org -Date: Wed Oct 11 22:42:26 2023 +0000 - - upstream: add ChannelTimeout support to the client, mirroring the + Add a -q flag to shut them up. - same option in the server. ok markus@ + ok dtucker@ - OpenBSD-Commit-ID: 55630b26f390ac063980cfe7ad8c54b03284ef02 + OpenBSD-Commit-ID: bec813de56a71adb5c1a76adcf49621130d24264 -commit 76e91e7238cdc5662bc818e2a48d466283840d23 -Author: djm@openbsd.org -Date: Wed Oct 11 22:41:05 2023 +0000 +commit 3e806d011855d6bd648ec95b9df630ebbd11c3bf +Author: naddy@openbsd.org +Date: Thu Jun 13 15:06:33 2024 +0000 - upstream: add support for reading ED25519 private keys in PEM PKCS8 - - format; ok markus@ tb@ + upstream: separate keywords with comma - OpenBSD-Commit-ID: 01b85c91757e6b057e9b23b8a23f96415c3c7174 + OpenBSD-Commit-ID: d65a99666202a8188c4991c18d14374a229f7be5 -commit fc77c8e352c0f44125425c05265e3a00c183d78a +commit abfd1f7a3cbd0a92581a0febba254b2f6649c0d9 Author: djm@openbsd.org -Date: Wed Oct 11 06:40:54 2023 +0000 +Date: Fri Jun 14 00:23:55 2024 +0000 - upstream: mention "none" is a valid argument to IdentityFile; bz3080 + upstream: specify an algorithm for ssh-keyscan, otherwise it will make - OpenBSD-Commit-ID: 1b4fb590ef731099349a7d468b77f02b240ac926 + multiple attempts simultaneously and confuse the test + + OpenBSD-Regress-ID: 6e910f3315c4345053db1bf5cbf61826b194d0b9 -commit c97520d23d1fe53d30725a2af25d2dddd6f2faff -Author: djm@openbsd.org -Date: Wed Oct 11 05:42:08 2023 +0000 +commit a8fbe2f7d0d96d299ee8e69769e3b51067978748 +Author: Damien Miller +Date: Thu Jun 13 16:41:29 2024 +1000 - upstream: in olde rcp/scp protocol mode, when rejecting a path from the + sshd: don't use argv[0] as PAM service name - server as not matching the glob that the client sent, log (at debug level) - the received pathname as well as the list of possible expected paths expanded - from the glob. bz2966 + sshd would implicitly use argv[0] as the PAM service name to + allow people to select different PAM service names by making + differently-named copies/links to the sshd binary. - OpenBSD-Commit-ID: 0bd8db8a595334ca86bca8f36e23fc0395315765 + Splitting sshd into sshd/sshd-session broke this, as the process + that starts PAM is always sshd-session and the user has no control + over this. + + Hardcode "sshd" as the default PAM service name unless/until we + figure out a better way. Should unbreak OSX integration tests. -commit 208c2b719879805983398160791d6a1ef9c2c3fc -Author: djm@openbsd.org -Date: Wed Oct 11 04:46:29 2023 +0000 +commit bf204bd05c3ae650f87e2b96527688579f59774c +Author: Damien Miller +Date: Thu Jun 13 15:00:28 2024 +1000 - upstream: s/%.100s/%s/ in SSH- banner construction as there's no - - reason to limit its size: the version string bring included is a compile time - constant going into an allocated banner string. + prepare for checking in autogenerated files - OpenBSD-Commit-ID: 0ef73304b9bf3e534c60900cd84ab699f859ebcd + We plan to check in automatically generated files (config.h.in, etc) on + release branches. These files are normally ignored by .gitignore, but + this shuffles the contents of this file to make it easy to un-ignore + them. -commit 0354790826b97c41bbd171a965574e159b58d83e -Author: tb@openbsd.org -Date: Tue Oct 10 06:49:54 2023 +0000 +commit 425f79a837489904c343b349ef00e09aeaa4e752 +Author: Damien Miller +Date: Thu Jun 13 14:41:33 2024 +1000 - upstream: Garbage collect cipher_get_keyiv_len() + typo in comment + +commit afe10313c1fa8d478af399ee7d54c8f85503013b +Author: Damien Miller +Date: Thu Jun 13 14:35:25 2024 +1000 + + fix PTY allocation on Cygwin, broken by sshd split - This is a compat20 leftover, unused since 2017. + Cygwin doesn't support FD passing and so used to disable post-auth + privilege separation entirely because privsep requires PTY allocation + to happen in the privileged monitor process with the PTY file + descriptors being passed back to the unprivileged process. - ok djm + This brings back a minimal version of the previous special treatment + for Cygwin (and any other platform that sets DISABLE_FD_PASSING): + privilege separation remains enabled, but PTY allocation happens in + the post-auth user process rather than the monitor. - OpenBSD-Commit-ID: 91fa5497c9dc6883064624ac27813a567883fdce + This either requires PTY allocation to not need privilege to begin + with (this appears to be the case on Cygwin), or the post-auth + privsep process retain privilege (other platforms that set the + DISABLE_FD_PASSING option). + + Keeping privileges here is bad, but the non-Cygwin systems that set + DISABLE_FD_PASSING are so deeply legacy that this is likely to be the + least of their problems. -commit 8d29ee4115001a02641386ae394992c65ed279e0 -Author: djm@openbsd.org -Date: Tue Oct 10 03:57:45 2023 +0000 +commit f66d4df5749551380a8c4ae642347675a0b6a2e9 +Author: Damien Miller +Date: Thu Jun 13 11:33:09 2024 +1000 - upstream: Reserve a range of "local extension" message numbers that - - OpenSSH promises not to use (comment change only) + delay lookup of privsep user until config loaded - OpenBSD-Commit-ID: e61795b453d4892d2c99ce1039112c4a00250e03 + sshd-session attempting to use options.kerberos_authentication to + decide whether it needed to lookup the privsep user before the + configuration was loaded. This caused it to get a placeholder value + that caused it always to try to lookup the privsep user, breaking at + least one test environment. -commit 90b0d73d63a706e85f6431f05a62d2ce1b476472 -Author: djm@openbsd.org -Date: Fri Oct 6 03:32:15 2023 +0000 +commit f1c42858b94f5d9b58867b34dce3afb39c6b56a8 +Author: Damien Miller +Date: Thu Jun 13 11:16:57 2024 +1000 - upstream: typo in error message - - OpenBSD-Regress-ID: 6a8edf0dc39941298e3780b147b10c0a600b4fee + missing file for PerSourcePenalties regress test -commit e84517f51532ec913d8fb01a8aab7307134774bb +commit 4de80ff4e6fab5a6bb0028e7d57c6c23d1485adb Author: djm@openbsd.org -Date: Fri Oct 6 03:25:14 2023 +0000 +Date: Wed Jun 12 22:36:00 2024 +0000 - upstream: Perform the softhsm2 setup as discrete steps rather than + upstream: split PerSourcePenalties address tracking. Previously it - as a long shell pipeline. Makes it easier to figure out what has happened - when it breaks. + used one shared table and overflow policy for IPv4 and IPv6 addresses, now it + will use separate tables and optionally different overflow policies. - OpenBSD-Regress-ID: b3f1292115fed65765d0a95414df16e27772d81c - -commit cb54becff4d776238e0e9072943ba0872260535d -Author: claudio@openbsd.org -Date: Sun Sep 24 08:14:13 2023 +0000 - - upstream: REGRESS_FAIL_EARLY defaults to yes now. So no need to + This prevents misbehaviour from IPv6 addresses (which are vastly easier + to obtain many of) from affecting IPv4 connections and may allow for + stricter overflow policies. - overload the value here anymore. OK tb@ bluhm@ + ok deraadt@ - OpenBSD-Regress-ID: f063330f1bebbcd373100afccebc91a965b14496 + OpenBSD-Commit-ID: 12637ed0aa4d5f1f3e702da42ea967cbd8bfdfd9 -commit f01f5137ceba65baf34ceac5a298c12ac01b1fef +commit 06ab4c6931b0aaa4334db2faaa7e1069e76d0df6 Author: jmc@openbsd.org -Date: Wed Oct 4 05:42:10 2023 +0000 +Date: Tue Jun 11 05:24:39 2024 +0000 - upstream: spelling fix; + upstream: do not mark up "(default: 20ms)"; - OpenBSD-Commit-ID: 493f95121567e5ab0d9dd1150f873b5535ca0195 + OpenBSD-Commit-ID: 54151ecdecfa1b67dcdda4fd24826ef6e2148ad4 -commit 80a2f64b8c1d27383cc83d182b73920d1e6a91f1 -Author: Damien Miller -Date: Wed Oct 4 15:34:10 2023 +1100 +commit cfe243cd9fde148ed060637876e27bb55ac78be9 +Author: djm@openbsd.org +Date: Tue Jun 11 02:54:51 2024 +0000 - crank version numbers + upstream: reap preauth net child if it hangs up during privsep message + + send, not just message receive + + OpenBSD-Commit-ID: 02a093f4ab4f8f83f0cd1ea2bb35b9ca420448f0 -commit f65f187b105d9b5c12fd750a211397d08c17c6d4 +commit b0a711c00b9c64afd1c9d6fb538275c6604a2676 Author: djm@openbsd.org -Date: Wed Oct 4 04:04:09 2023 +0000 +Date: Tue Jun 11 01:58:27 2024 +0000 - upstream: openssh-9.5 + upstream: fix PIDFILE handling, broken for SUDO=doas in last commit - OpenBSD-Commit-ID: 5e0af680480bd3b6f5560cf840ad032d48fd6b16 + here + + OpenBSD-Regress-ID: 96fec579af228f87a036e94801eb294af9074625 -commit ffe27e54a4bb18d5d3bbd3f4cc93a41b8d94dfd2 +commit 90fb801e2d9241be50a2a7ff79428386442a041f Author: djm@openbsd.org -Date: Wed Oct 4 04:03:50 2023 +0000 +Date: Tue Jun 11 02:00:30 2024 +0000 - upstream: add some cautionary text about % token expansion and + upstream: reap the pre-auth [net] child if it hangs up during privsep - shell metacharacters; based on report from vinci AT protonmail.ch + message sending, not just receiving - OpenBSD-Commit-ID: aa1450a54fcee2f153ef70368d90edb1e7019113 + OpenBSD-Commit-ID: f7341605bf08c4c15830910446e6775323f2f8cb -commit 60ec3d54fd1ebfe2dda75893fa1e870b8dffbb0d +commit ef878d58798f6688c7f4d4e417dc0c29023ea831 Author: djm@openbsd.org -Date: Tue Oct 3 23:56:10 2023 +0000 +Date: Tue Jun 11 01:23:25 2024 +0000 - upstream: fix link to agent draft; spotted by Jann Horn + upstream: a little more RB_TREE paranoia - OpenBSD-Commit-ID: ff5bda21a83ec013db683e282256a85201d2dc4b - -commit 12e2d4b13f6f63ce2de13cbfcc9e4d0d4b4ab231 -Author: Damien Miller -Date: Wed Oct 4 10:54:04 2023 +1100 - - use portable provider allowlist path in manpage - - spotted by Jann Horn + OpenBSD-Commit-ID: 8dc2fd21eebd8830c4a4d25461ac4fe228e11156 -commit 6c2c6ffde75df95fd838039850d3dd3d84956d87 -Author: deraadt@openbsd.org -Date: Tue Sep 19 20:37:07 2023 +0000 +commit fc4e96b2174d6a894d2033421699d091679baced +Author: djm@openbsd.org +Date: Tue Jun 11 01:22:25 2024 +0000 - upstream: typo; from Jim Spath + upstream: fix off-by-one comparison for PerSourcePenalty - OpenBSD-Commit-ID: 2f5fba917b5d4fcf93d9e0b0756c7f63189e228e + OpenBSD-Commit-ID: af4f5d01c41ef870b23e55655bfbf73474a6c02b -commit b6b49130a0089b297245ee39e769231d7c763014 +commit 82c836df4ff41145553cd7adb11c5b985aeaa06f Author: djm@openbsd.org -Date: Sun Sep 10 23:12:32 2023 +0000 +Date: Tue Jun 11 01:21:41 2024 +0000 - upstream: rename remote_glob() -> sftp_glob() to match other API + upstream: move tree init before possible early return - OpenBSD-Commit-ID: d9dfb3708d824ec02970a84d96cf5937e0887229 + OpenBSD-Commit-ID: 72e2c5b69f151c08a7c5bf5ad929b97a92c273df -commit 21b79af6c8d2357c822c84cef3fbdb8001ed263b +commit a2300f015cc4939c4d9c564b58b74e71202dc978 Author: djm@openbsd.org -Date: Sun Sep 10 03:51:55 2023 +0000 +Date: Tue Jun 11 01:07:35 2024 +0000 - upstream: typo in comment + upstream: update to mention that PerSourcePenalties default to - OpenBSD-Commit-ID: 69285e0ce962a7c6b0ab5f17a293c60a0a360a18 - -commit 41232d25532b4d2ef6c5db62efc0cf50a79d26ca -Author: Darren Tucker -Date: Sun Sep 10 15:45:38 2023 +1000 - - Use zero-call-used-regs=used with Apple compilers. + being enabled and document the default values for each parameter. - Apple's versions of clang have version numbers that do not match the - corresponding upstream clang versions. Unfortunately, they do still - have the clang-15 zero-call-used-regs=all bug, so for now use the value - that doesn't result in segfaults. We could allowlist future versions - that are known to work. bz#3584 (and probably also our github CI - failures). + OpenBSD-Commit-ID: b981288bddfb097aad269f62df4081c688ce0034 -commit 90ccc5918ea505bf156c31148b6b59a1bf5d6dc6 +commit 41987efd356d3fc30139aeab4b09374acf8f91a0 Author: djm@openbsd.org -Date: Sun Sep 10 03:25:53 2023 +0000 +Date: Tue Jun 11 00:44:52 2024 +0000 - upstream: randomise keystroke obfuscation intervals and average + upstream: reap the [net] child if it hangs up while writing privsep - interval rate. ok dtucker@ + message payloads, not just the message header - OpenBSD-Commit-ID: 05f61d051ab418fcfc4857ff306e420037502382 + OpenBSD-Commit-ID: 24dbd400aa381ac96be7ed2dd49018487dfef6ce -commit bd1b9e52f5fa94d87223c90905c5fdc1a7c32aa6 +commit 6211aa085fa91155a24922e5329576ac9a8f3175 Author: djm@openbsd.org -Date: Fri Sep 8 06:34:24 2023 +0000 +Date: Tue Jun 11 00:40:21 2024 +0000 - upstream: fix sizeof(*ptr) instead sizeof(ptr) in realloc (pointer here - - is char**, so harmless); spotted in CID 416964 + upstream: log waitpid() status for abnormal exits - OpenBSD-Commit-ID: c61caa4a5a667ee20bb1042098861e6c72c69002 + OpenBSD-Commit-ID: b317930e06b51819c1a2bc6a4359764fecfb1c2d -commit c4f966482983e18601eec70a1563115de836616f +commit a59634c7adb9ae988748d99963dfafb3070d8d41 Author: djm@openbsd.org -Date: Fri Sep 8 06:10:57 2023 +0000 +Date: Tue Jun 11 00:36:20 2024 +0000 - upstream: regress test recursive remote-remote directories copies where - - the directory contains a symlink to another directory. - - also remove errant `set -x` that snuck in at some point + upstream: correct error message - OpenBSD-Regress-ID: 1c94a48bdbd633ef2285954ee257725cd7bc456f + OpenBSD-Commit-ID: 581f60f73099083392887206860229ab104620ed -commit 5e1dfe5014ebc194641678303e22ab3bba15f4e5 -Author: djm@openbsd.org -Date: Fri Sep 8 06:10:02 2023 +0000 +commit fa7d7a667f2ee031e72873e36de2d2a36bca973b +Author: deraadt@openbsd.org +Date: Fri Jun 7 13:23:30 2024 +0000 - upstream: fix recursive remote-remote copies of directories that + upstream: avoid shadowing issues which some compilers won't accept - contain symlinks to other directories (similar to bz3611) + ok djm - OpenBSD-Commit-ID: 7e19d2ae09b4f941bf8eecc3955c9120171da37f + OpenBSD-Commit-ID: 1e89572397dda83433d58c4fa6333a08f51170d4 -commit 7c0ce2bf98b303b6ad91493ee3247d96c18ba1f6 -Author: djm@openbsd.org -Date: Fri Sep 8 05:50:57 2023 +0000 +commit 3ad4cd9eeca5c9bc6706db44b6de88e2e4513fd6 +Author: jmc@openbsd.org +Date: Thu Jun 6 21:14:49 2024 +0000 - upstream: regress test for recursive copies of directories containing + upstream: escape the final dot at eol in "e.g." to avoid double - symlinks to other directories. bz3611, ok dtucker@ + spacing; - OpenBSD-Regress-ID: eaa4c29cc5cddff4e72a16bcce14aeb1ecfc94b9 + OpenBSD-Commit-ID: 0a9fb10bc9f7d577afe2da3f498a08bc431115b9 -commit 2de990142a83bf60ef694378b8598706bc654b08 +commit 0e0c69761a4c33ccd4a256560f522784a753d1a8 Author: djm@openbsd.org -Date: Fri Sep 8 05:56:13 2023 +0000 +Date: Thu Jun 6 20:25:48 2024 +0000 - upstream: the sftp code was one of my first contributions to + upstream: enable PerSourcePenalties by default. - OpenSSH and it shows - the function names are terrible. + ok markus - Rename do_blah() to sftp_blah() to make them less so. + NB. if you run a sshd that accepts connections from behind large NAT + blocks, proxies or anything else that aggregates many possible users + behind few IP addresses, then this change may cause legitimate traffic + to be denied. - Completely mechanical except for sftp_stat() and sftp_lstat() which - change from returning a pointer to a static variable (error-prone) to - taking a pointer to a caller-provided receiver. + Please read the PerSourcePenalties, PerSourcePenaltyExemptList and + PerSourceNetBlockSize options in sshd_config(5) for how to tune your + sshd(8) for your specific circumstances. - OpenBSD-Commit-ID: eb54d6a72d0bbba4d623e2175cf5cc4c75dc2ba4 + OpenBSD-Commit-ID: 24a0e5c23d37e5a63e16d2c6da3920a51078f6ce -commit 249d8bd0472b53e3a2a0e138b4c030a31e83346a +commit bd1f74741daabeaf20939a85cd8cec08c76d0bec Author: djm@openbsd.org -Date: Fri Sep 8 05:50:12 2023 +0000 +Date: Thu Jun 6 20:20:42 2024 +0000 - upstream: fix scp in SFTP mode recursive upload and download of + upstream: mention that PerSourcePenalties don't affect concurrent - directories that contain symlinks to other directories. In scp mode, the - links would be followed, but in SFTP mode they were not. bz3611, ok dtucker@ + in-progress connections. - OpenBSD-Commit-ID: 9760fda668eaa94a992250d7670dfbc62a45197c + OpenBSD-Commit-ID: 20389da6264f2c97ac3463edfaa1182c212d420c -commit 0e1f4401c466fa4fdaea81b6dadc8dd1fc4cf0af +commit 9774b938578327d88a651f4c63c504809717590a Author: djm@openbsd.org -Date: Wed Sep 6 23:36:09 2023 +0000 +Date: Thu Jun 6 19:49:25 2024 +0000 - upstream: regression test for override of subsystem in match blocks + upstream: regress test for PerSourcePenalties - OpenBSD-Regress-ID: 5f8135da3bfda71067084c048d717b0e8793e87c + OpenBSD-Regress-ID: a1af13d411b25a727742644459d26480b9a1b0f1 -commit 8a1450c62035e834d8a79a5d0d1c904236f9dcfe +commit b8ebd86cefe9812204a10c028dc90de29918667d Author: djm@openbsd.org -Date: Wed Sep 6 23:35:35 2023 +0000 +Date: Thu Jun 6 19:48:40 2024 +0000 - upstream: allow override of Sybsystem directives in sshd Match - - blocks + upstream: make sure logs are saved from sshd run via start_sshd - OpenBSD-Commit-ID: 3911d18a826a2d2fe7e4519075cf3e57af439722 + OpenBSD-Regress-ID: de4ef0e32e3ab85ff3a6c36eb08d1909c0dd1b4a -commit 6e52826e2a74d077147a82ead8d4fbd5b54f4e3b +commit d7b2070bdaa4ebbfafb9975c1d5a62b73289d31f Author: djm@openbsd.org -Date: Wed Sep 6 23:26:37 2023 +0000 +Date: Thu Jun 6 19:47:48 2024 +0000 - upstream: allocate the subsystems array as necessary and remove the - - fixed limit of subsystems. Saves a few kb of memory in the server and makes - it more like the other options. + upstream: simplify - OpenBSD-Commit-ID: e683dfca6bdcbc3cc339bb6c6517c0c4736a547f + OpenBSD-Regress-ID: 50316e0d1ae0c0a057a45af042253e54ce23d11c -commit e19069c9fac4c111d6496b19c7f7db43b4f07b4f +commit e6ea3d224513b6bfb93818809d4c7397f5995ba2 Author: djm@openbsd.org -Date: Wed Sep 6 23:23:53 2023 +0000 +Date: Thu Jun 6 18:48:13 2024 +0000 - upstream: preserve quoting of Subsystem commands and arguments. + upstream: prepare for PerSourcePenalties being enabled by default - This may change behaviour of exotic configurations, but the most common - subsystem configuration (sftp-server) is unlikely to be affected. + in future - OpenBSD-Commit-ID: 8ffa296aeca981de5b0945242ce75aa6dee479bf + OpenBSD-Regress-ID: 5236c6d1c823997aac5a35e2915da30f1903bec7 -commit 52dfe3c72d98503d8b7c6f64fc7e19d685636c0b +commit c0cb3b8c837761816a60a3cdb54062668df09652 Author: djm@openbsd.org -Date: Wed Sep 6 23:21:36 2023 +0000 +Date: Thu Jun 6 19:50:01 2024 +0000 - upstream: downgrade duplicate Subsystem directives from being a - - fatal error to being a debug message to match behaviour with just about all - other directives. + upstream: disable stderr redirection before closing fds - OpenBSD-Commit-ID: fc90ed2cc0c18d4eb8e33d2c5e98d25f282588ce + OpenBSD-Commit-ID: d42cb895ee4542098050367fc35321c9303f003a -commit 1ee0a16e07b6f0847ff463d7b5221c4bf1876e25 +commit 81c1099d22b81ebfd20a334ce986c4f753b0db29 Author: djm@openbsd.org -Date: Wed Sep 6 23:18:15 2023 +0000 +Date: Thu Jun 6 17:15:25 2024 +0000 - upstream: handle cr+lf (instead of just cr) in sshsig signature + upstream: Add a facility to sshd(8) to penalise particular - files + problematic client behaviours, controlled by two new sshd_config(5) options: + PerSourcePenalties and PerSourcePenaltyExemptList. - OpenBSD-Commit-ID: 647460a212b916540016d066568816507375fd7f - -commit e1c284d60a928bcdd60bc575c6f9604663502770 -Author: job@openbsd.org -Date: Mon Sep 4 10:29:58 2023 +0000 - - upstream: Generate Ed25519 keys when invoked without arguments + When PerSourcePenalties are enabled, sshd(8) will monitor the exit + status of its child pre-auth session processes. Through the exit + status, it can observe situations where the session did not + authenticate as expected. These conditions include when the client + repeatedly attempted authentication unsucessfully (possibly indicating + an attack against one or more accounts, e.g. password guessing), or + when client behaviour caused sshd to crash (possibly indicating + attempts to exploit sshd). - Ed25519 public keys are very convenient due to their small size. - OpenSSH has supported Ed25519 since version 6.5 (January 2014). + When such a condition is observed, sshd will record a penalty of some + duration (e.g. 30 seconds) against the client's address. If this time + is above a minimum threshold specified by the PerSourcePenalties, then + connections from the client address will be refused (along with any + others in the same PerSourceNetBlockSize CIDR range). - OK djm@ markus@ sthen@ deraadt@ + Repeated offenses by the same client address will accrue greater + penalties, up to a configurable maximum. A PerSourcePenaltyExemptList + option allows certain address ranges to be exempt from all penalties. - OpenBSD-Commit-ID: f498beaad19c8cdcc357381a60df4a9c69858b3f - -commit 694150ad92765574ff82a18f4e86322bd3231e68 -Author: djm@openbsd.org -Date: Mon Sep 4 00:08:14 2023 +0000 - - upstream: trigger keystroke timing obfucation only if the channels + We hope these options will make it significantly more difficult for + attackers to find accounts with weak/guessable passwords or exploit + bugs in sshd(8) itself. - layer enqueud some data in the last poll() cycle; this avoids triggering the - obfuscatior for non-channels data like ClientAlive probes and also fixes a - related problem were the obfucations would be triggered on fully quiescent - connections. + PerSourcePenalties is off by default, but we expect to enable it + automatically in the near future. - Based on / tested by naddy@ + much feedback markus@ and others, ok markus@ - OpenBSD-Commit-ID: d98f32dc62d7663ff4660e4556e184032a0db123 + OpenBSD-Commit-ID: 89ded70eccb2b4926ef0366a4d58a693de366cca -commit b5fd97896b59a3a46245cf438cc8b16c795d9f74 -Author: djm@openbsd.org -Date: Mon Sep 4 00:04:02 2023 +0000 +commit 916b0b6174e203cf2c5ec9bcf409472eb7ffbf43 +Author: Damien Miller +Date: Fri Jun 7 03:31:02 2024 +1000 - upstream: avoid bogus "obfuscate_keystroke_timing: stopping ..." - - debug messages when keystroke timing obfuscation was never started; spotted - by naddy@ - - OpenBSD-Commit-ID: 5c270d35f7d2974db5c1646e9c64188f9393be31 + whitespace -commit ccf7d913db34e49b7a6db1b8331bd402004c840d -Author: djm@openbsd.org -Date: Mon Sep 4 00:01:46 2023 +0000 +commit 49b55e44182b8294419aa580cbf043d5b9e3d953 +Author: deraadt@openbsd.org +Date: Tue Jun 4 15:14:45 2024 +0000 - upstream: make channel_output_poll() return a flag indicating + upstream: enable -fret-clean on amd64, for libc libcrypto ld.so - whether channel data was enqueued. Will be used to improve keystroke timing - obfuscation. Problem spotted by / tested by naddy@ + kernel, and all the ssh tools. The dynamic objects are entirely ret-clean, + static binaries will contain a blend of cleaning and non-cleaning callers. - OpenBSD-Commit-ID: f9776c7b0065ba7c3bbe50431fd3b629f44314d0 + OpenBSD-Commit-ID: 112aacedd3b61cc5c34b1fa6d9fb759214179172 -commit 43254b326ac6e2131dbd750f9464dc62c14bd5a7 +commit cc80d51d034bcb24fd0f2564a4bdf1612000a2a2 +Author: Damien Miller +Date: Wed Jun 5 02:21:30 2024 +1000 + + remove PRIVSEP macros for osx + +commit 8785491123d4d722b310c20f383570be758f8263 Author: djm@openbsd.org -Date: Sun Sep 3 23:59:32 2023 +0000 +Date: Sat Jun 1 07:03:37 2024 +0000 - upstream: set interactive mode for ControlPersist sessions if they + upstream: be really strict with fds reserved for communication with the - originally requested a tty; enables keystroke timing obfuscation for most - ControlPersist sessions. Spotted by naddy@ + separate sshd-session process - reserve them early and fatal if we can't + dup2(2) them later. The pre-split fallback to re-reading the configuration + files is not possible, so sshd-session absolutely requires the fd the + configuration is passed over to be in order. - OpenBSD-Commit-ID: 72783a26254202e2f3f41a2818a19956fe49a772 + ok deraadt@ + + OpenBSD-Commit-ID: 308a98ef3c8a6665ebf92c7c9a0fc9600ccd7065 -commit ff3eda68ceb2e2bb8f48e3faceb96076c3e85c20 -Author: Darren Tucker -Date: Thu Aug 31 23:02:35 2023 +1000 +commit f1c8918cb98459910fb159373baea053ba4108c0 +Author: Damien Miller +Date: Fri May 31 19:12:26 2024 +1000 - Set LLONG_MAX for C89 test. + depend + +commit 94b4866cb1f4b0ed29a9f367047b30f81002316f +Author: Damien Miller +Date: Fri May 31 19:11:14 2024 +1000 + + rename need_privsep to need_chroot - If we don't have LLONG_MAX, configure will figure out that it can get it - by setting -std=gnu99, at which point we won't be testing C89 any more. - To avoid this, feed it in via CFLAGS. + privsep is mandatory, chroot is optional (disabled when running + sshd as non-root) -commit f98031773db361424d59e3301aa92aacf423d920 +commit e68a95142e5024b144f8eeccd5ffdee42c34f44c +Author: Damien Miller +Date: Fri May 31 19:05:34 2024 +1000 + + remove remaining use_privsep mention + +commit b21d271f651d2536dca819cc6d74032fe98634db Author: djm@openbsd.org -Date: Tue Aug 29 02:50:10 2023 +0000 +Date: Fri May 31 09:01:08 2024 +0000 - upstream: make PerSourceMaxStartups first-match-wins; ok dtucker@ + upstream: warn when -r (deprecated option to disable re-exec) is - OpenBSD-Commit-ID: dac0c24cb709e3c595b8b4f422a0355dc5a3b4e7 + passed + + OpenBSD-Commit-ID: 73145ef5150edbe3ce7889f0844ed8fa6155f551 -commit cfa66857db90cd908de131e0041a50ffc17c7df8 +commit a4b5bc246cbca476deeeb4462aa31746a56e3021 Author: djm@openbsd.org -Date: Mon Aug 28 09:52:09 2023 +0000 +Date: Fri May 31 08:49:35 2024 +0000 - upstream: descriptive text shouldn't be under .Cm + upstream: typos - OpenBSD-Commit-ID: b1afaeb456a52bc8a58f4f9f8b2f9fa8f6bf651b + OpenBSD-Commit-ID: edfa72eb06bfa65da30fabf7d2fe76d2d33f77bf -commit 01dbf3d46651b7d6ddf5e45d233839bbfffaeaec +commit 8054b906983ceaed01fabd8188d3dac24c05ba39 Author: djm@openbsd.org -Date: Mon Aug 28 09:48:11 2023 +0000 +Date: Mon May 27 01:52:26 2024 +0000 - upstream: limit artificial login delay to a reasonable maximum (5s) - - and don't delay at all for the "none" authentication mechanism. Patch by - Dmitry Belyavskiy in bz3602 with polish/ok dtucker@ + upstream: don't need sys/queue.h here - OpenBSD-Commit-ID: 85b364676dd84cf1de0e98fc2fbdcb1a844ce515 + OpenBSD-Commit-ID: dd137396828171eb19e4911581812ca58de6c578 -commit 528da5b9d7c5da01ed7a73ff21c722e1b5326006 -Author: jmc@openbsd.org -Date: Mon Aug 28 05:32:28 2023 +0000 +commit 210d4239733da6180ce853538aeb9413d5c62ad5 +Author: naddy@openbsd.org +Date: Sun May 26 20:35:12 2024 +0000 - upstream: add spacing for punctuation when macro args; + upstream: remove references to SSH1 and DSA server keys - OpenBSD-Commit-ID: e80343c16ce0420b2aec98701527cf90371bd0db + OpenBSD-Commit-ID: 57cc1c98d4f998981473734f144b904af7d178a2 -commit 3867361ca691d0956ef7d5fb8181cf554a91d84a -Author: djm@openbsd.org -Date: Mon Aug 28 04:06:52 2023 +0000 +commit f0b9261d7fdd0ef86806b49fe76344bd16770cd0 +Author: jsg@openbsd.org +Date: Thu May 23 23:47:16 2024 +0000 - upstream: explicit long long type in timing calculations (doesn't + upstream: remove unused struct fwd_perm_list, no decl with complete - matter, since the range is pre-clamped) + type ok djm@ - OpenBSD-Commit-ID: f786ed902d04a5b8ecc581d068fea1a79aa772de + OpenBSD-Commit-ID: 416fb3970b7e73c76d2963c4f00cf96f2b2ee2fb -commit 7603ba71264e7fa938325c37eca993e2fa61272f -Author: djm@openbsd.org -Date: Mon Aug 28 03:31:16 2023 +0000 +commit 2477a98c3ef78e63b11a1393656e00288f52ae97 +Author: naddy@openbsd.org +Date: Wed May 22 15:24:55 2024 +0000 - upstream: Add keystroke timing obfuscation to the client. + upstream: Do not pass -Werror twice when building with clang. - This attempts to hide inter-keystroke timings by sending interactive - traffic at fixed intervals (default: every 20ms) when there is only a - small amount of data being sent. It also sends fake "chaff" keystrokes - for a random interval after the last real keystroke. These are - controlled by a new ssh_config ObscureKeystrokeTiming keyword/ + OpenBSD-Commit-ID: 5f378c38ad8976d507786dc4db9283a879ec8cd0 + +commit 435844f5675245b4271f8581f15e6d1f34fde3bc +Author: miod@openbsd.org +Date: Wed May 22 11:49:36 2024 +0000 + + upstream: Do not pass -Werror if building with gcc 3, for asn1.h - feedback/ok markus@ + and bio.h cause (admittedly bogus) warnings with gcc 3. - OpenBSD-Commit-ID: 02231ddd4f442212820976068c34a36e3c1b15be + OpenBSD-Commit-ID: fb39324748824cb0387e9d67c41d1bef945c54ea -commit dce6d80d2ed3cad2c516082682d5f6ca877ef714 +commit fc5dc092830de23767c6ef67baa18310a64ee533 Author: djm@openbsd.org -Date: Mon Aug 28 03:28:43 2023 +0000 +Date: Wed May 22 04:20:00 2024 +0000 - upstream: Introduce a transport-level ping facility + upstream: this test has been broken since 2014, and has been - This adds a pair of SSH transport protocol messages SSH2_MSG_PING/PONG - to implement a ping capability. These messages use numbers in the "local - extensions" number space and are advertised using a "ping@openssh.com" - ext-info message with a string version number of "0". + testing the same key exchange algorithm repeatedly instead of testing all of + them. Spotted by nreilly AT blackberry.com in bz3692 - ok markus@ + Who broke the test? me. - OpenBSD-Commit-ID: b6b3c4cb2084c62f85a8dc67cf74954015eb547f + OpenBSD-Regress-ID: 48f4f5946276f975667141957d25441b3c9a50e2 -commit d2d247938b38b928f8a6e1a47a330c5584d3a358 -Author: tobhe@openbsd.org -Date: Mon Aug 21 21:16:18 2023 +0000 +commit fd4816791beaed2fdae7eea3e1494d1972b2a39d +Author: anton@openbsd.org +Date: Sun May 19 19:10:01 2024 +0000 - upstream: Log errors in kex_exchange_identification() with level - - verbose instead of error to reduce preauth log spam. All of those get logged - with a more generic error message by sshpkt_fatal(). + upstream: Add missing kex-names.c source file required since the - feedback from sthen@ - ok djm@ + ssh split. - OpenBSD-Commit-ID: bd47dab4695b134a44c379f0e9a39eed33047809 + OpenBSD-Regress-ID: ca666223f828fc4b069cb9016bff1eb50faf9fbb -commit 9d7193a8359639801193ad661a59d1ae4dc3d302 -Author: djm@openbsd.org -Date: Mon Aug 21 04:59:54 2023 +0000 +commit beccb7319c5449f6454889013403c336446d622e +Author: naddy@openbsd.org +Date: Fri May 17 14:42:00 2024 +0000 - upstream: correct math for ClientAliveInterval that caused the - - probes to be sent less frequently than configured; from Dawid Majchrzak + upstream: remove duplicate copy of relink kit for sshd-session - OpenBSD-Commit-ID: 641153e7c05117436ddfc58267aa267ca8b80038 + OpenBSD-Commit-ID: 6d2ded4cd91d4d727c2b26e099b91ea935bed504 -commit 3c6ab63b383b0b7630da175941e01de9db32a256 -Author: Darren Tucker -Date: Fri Aug 25 14:48:02 2023 +1000 +commit dcd79fa141311c287e0595ede684b7116122fae0 +Author: jsg@openbsd.org +Date: Fri May 17 06:42:04 2024 +0000 - Include Portable version in sshd version string. + upstream: remove prototypes with no matching function; ok djm@ - bz#3608, ok djm@ + OpenBSD-Commit-ID: 6d9065dadea5f14a01bece0dbfe2fba1be31c693 -commit 17fa6cd10a26e193bb6f65d21264d2fe553bcd87 -Author: Darren Tucker -Date: Mon Aug 21 19:47:58 2023 +1000 +commit 6454a05e7c6574d70adf17efe505a8581a86ca4f +Author: jsg@openbsd.org +Date: Fri May 17 06:38:00 2024 +0000 - obsd-arm64 host is real hardware... + upstream: remove externs for removed vars; ok djm@ - so put in the correct config location. + OpenBSD-Commit-ID: f51ea791d45c15d4927eb4ae7d877ccc1e5a2aab -commit 598ca75c85acaaacee5ef954251e489cc20d7be9 -Author: Darren Tucker -Date: Mon Aug 21 18:38:36 2023 +1000 +commit f3e4db4601ef7d2feb1d6f7447e432aaf353a616 +Author: deraadt@openbsd.org +Date: Fri May 17 06:11:17 2024 +0000 - Add OpenBSD ARM64 test host. + upstream: -Werror was turned on (probably just for development), + + and this is a simple way to satisfy older gcc. + + OpenBSD-Commit-ID: 7f698df54384b437ce33ab7405f0b86c87019e86 -commit 1acac79bfbe207e8db639e8043524962037c8feb -Author: Darren Tucker -Date: Mon Aug 21 18:05:26 2023 +1000 +commit 24a1f3e5ad6f4a49377d4c74c36637e9a239efd0 +Author: Damien Miller +Date: Fri May 17 14:50:43 2024 +1000 - Add test for zlib development branch. + attempt at updating RPM specs for sshd-session -commit 84efebf352fc700e9040c8065707c63caedd36a3 +commit 17b566eeb7a0c6acc9c48b35c08885901186f861 Author: djm@openbsd.org -Date: Mon Aug 21 04:36:46 2023 +0000 +Date: Fri May 17 04:42:13 2024 +0000 - upstream: want stdlib.h for free(3) + upstream: g/c unused variable - OpenBSD-Commit-ID: 743af3c6e3ce5e6cecd051668f0327a01f44af29 + OpenBSD-Commit-ID: aa6ef0778a1f1bde0d73efba72a777c48d2bd010 -commit cb4ed12ffc332d1f72d054ed92655b5f1c38f621 -Author: Darren Tucker -Date: Sat Aug 19 07:39:08 2023 +1000 +commit 01fb82eb2aa0a4eaf5c394ea8bb37ea4c26f8a3f +Author: jsg@openbsd.org +Date: Fri May 17 02:39:11 2024 +0000 - Fix zlib version check for 1.3 and future version. + upstream: spelling; ok djm@ - bz#3604. - -commit 25b75e21f16bccdaa472ea1889b293c9bd51a87b -Author: Darren Tucker -Date: Mon Aug 14 11:10:08 2023 +1000 - - Add 9.4 branch to CI status page. + OpenBSD-Commit-ID: bdea29bb3ed2a5a7782999c4c663b219d2270483 -commit 803e22eabd3ba75485eedd8b7b44d6ace79f2052 +commit b88b690e99145a021fc1a1a116a11e0bce0594e7 Author: djm@openbsd.org -Date: Fri Aug 18 01:37:41 2023 +0000 +Date: Fri May 17 01:45:22 2024 +0000 - upstream: fix regression in OpenSSH 9.4 (mux.c r1.99) that caused - - multiplexed sessions to ignore SIGINT under some circumstances. Reported by / - feedback naddy@, ok dtucker@ + upstream: allow overriding the sshd-session binary path - OpenBSD-Commit-ID: 4d5c6c894664f50149153fd4764f21f43e7d7e5a + OpenBSD-Regress-ID: 5058cd1c4b6ca1a15474e33546142931d9f964da -commit e706bca324a70f68dadfd0ec69edfdd486eed23a -Author: djm@openbsd.org -Date: Wed Aug 16 16:14:11 2023 +0000 - - upstream: defence-in-depth MaxAuthTries check in monitor; ok markus - - OpenBSD-Commit-ID: 65a4225dc708e2dae71315adf93677edace46c21 - -commit d1ab7eb90474df656d5e9935bae6df0bd000d343 -Author: djm@openbsd.org -Date: Mon Aug 14 03:37:00 2023 +0000 - - upstream: add message number of SSH2_MSG_NEWCOMPRESS defined in RFC8308 - - OpenBSD-Commit-ID: 6c984171c96ed67effd7b5092f3d3975d55d6028 - -commit fa8da52934cb7dff6f660a143276bdb28bb9bbe1 -Author: Darren Tucker -Date: Sun Aug 13 15:01:27 2023 +1000 - - Add obsd72 and obsd73 test targets. - -commit f9f18006678d2eac8b0c5a5dddf17ab7c50d1e9f -Author: djm@openbsd.org -Date: Thu Aug 10 23:05:48 2023 +0000 - - upstream: better debug logging of sessions' exit status - - OpenBSD-Commit-ID: 82237567fcd4098797cbdd17efa6ade08e1a36b0 - -commit a8c57bcb077f0cfdffcf9f23866bf73bb93e185c -Author: naddy@openbsd.org -Date: Thu Aug 10 14:37:32 2023 +0000 - - upstream: drop a wayward comma, ok jmc@ - - OpenBSD-Commit-ID: 5c11fbb9592a29b37bbf36f66df50db9d38182c6 - -commit e962f9b318a238db1becc53c2bf79dd3a49095b4 -Author: Damien Miller -Date: Thu Aug 10 11:10:22 2023 +1000 - - depend - -commit 0fcb60bf83130dfa428bc4422b3a3ac20fb528af -Author: Damien Miller -Date: Thu Aug 10 11:05:42 2023 +1000 - - update versions in RPM specs - -commit d0cee4298491314f09afa1c4383a66d913150b26 -Author: Damien Miller -Date: Thu Aug 10 11:05:14 2023 +1000 - - update version in README - -commit 78b4dc6684f4d35943b46b24ee645edfdb9974f5 -Author: djm@openbsd.org -Date: Thu Aug 10 01:01:07 2023 +0000 - - upstream: openssh-9.4 - - OpenBSD-Commit-ID: 71fc1e01a4c4ea061b252bd399cda7be757e6e35 - -commit 58ca4f0aa8c4306ac0a629c9a85fb1efaf4ff092 -Author: Darren Tucker -Date: Thu Aug 10 11:30:24 2023 +1000 - - Only include unistd.h once. - -commit 3961ed02dc578517a9d2535128cff5c3a5460d28 -Author: Damien Miller -Date: Thu Aug 10 09:08:49 2023 +1000 - - wrap poll.h include in HAVE_POLL_H - -commit e535fbe2af893046c28adfcd787c1fdbae36a24a -Author: dtucker@openbsd.org -Date: Fri Aug 4 06:32:40 2023 +0000 - - upstream: Apply ConnectTimeout to multiplexing local socket - - connections. If the multiplex socket exists but the connection times out, - ssh will fall back to a direct connection the same way it would if the socket - did not exist at all. ok djm@ - - OpenBSD-Commit-ID: 2fbe1a36d4a24b98531b2d298a6557c8285dc1b4 - -commit 9d92e7b24848fcc605945f7c2e3460c7c31832ce -Author: Darren Tucker -Date: Thu Aug 3 19:35:33 2023 +1000 - - Fix RNG seeding for OpenSSL w/out self seeding. - - When sshd is built with an OpenSSL that does not self-seed, it would - fail in the preauth privsep process while handling a new connection. - Sanity checked by djm@ - -commit f70010d9b0b3e7e95de8aa0b961e1d74362cfb5d -Author: djm@openbsd.org -Date: Wed Aug 2 23:04:38 2023 +0000 - - upstream: CheckHostIP has defaulted to 'no' for a while; make the - - commented- out config option match. From Ed Maste - - OpenBSD-Commit-ID: e66e934c45a9077cb1d51fc4f8d3df4505db58d9 - -commit c88a8788f9865d02b986d00405b9f0be65ad0b5a -Author: dtucker@openbsd.org -Date: Tue Aug 1 08:15:04 2023 +0000 - - upstream: remove unnecessary if statement. - - github PR#422 from eyalasulin999, ok djm@ - - OpenBSD-Commit-ID: 2b6b0dde4407e039f58f86c8d2ff584a8205ea55 - -commit 77b8b865cd5a8c79a47605c0c5b2bacf4692c4d5 -Author: jmc@openbsd.org -Date: Fri Jul 28 05:42:36 2023 +0000 - - upstream: %C is a callable macro in mdoc(7) - - so, as we do for %D, escape it; - - OpenBSD-Commit-ID: 538cfcddbbb59dc3a8739604319491dcb8e0c0c9 - -commit e0f91aa9c2fbfc951e9ced7e1305455fc614d3f2 -Author: djm@openbsd.org -Date: Fri Jul 28 05:33:15 2023 +0000 - - upstream: don't need to start a command here; use ssh -N instead. - - Fixes failure on cygwin spotted by Darren - - OpenBSD-Regress-ID: ff678a8cc69160a3b862733d935ec4a383f93cfb - -commit f446a44f30bc680e0d026a4204844b02646c1c2d -Author: djm@openbsd.org -Date: Wed May 17 05:52:01 2023 +0000 - - upstream: add LTESTS_FROM variable to allow skipping of tests up to - - a specific point. e.g. "make LTESTS_FROM=t-sftp" will only run the sftp.sh - test and subsequent ones. ok dtucker@ - - OpenBSD-Regress-ID: 07f653de731def074b29293db946042706fcead3 - -commit 8eb8899d612440a9b608bee7f916081d3d0b7812 -Author: djm@openbsd.org -Date: Fri May 12 06:37:42 2023 +0000 - - upstream: test ChrootDirectory in Match block - - OpenBSD-Regress-ID: a6150262f39065939f025e546af2a346ffe674c1 - -commit e43f43d3f19516222e9a143468ea0dc1b3ab67b6 -Author: djm@openbsd.org -Date: Fri May 12 06:36:27 2023 +0000 - - upstream: better error messages - - OpenBSD-Regress-ID: 55e4186604e80259496d841e690ea2090981bc7a - -commit 6958f00acf3b9e0b3730f7287e69996bcf3ceda4 -Author: djm@openbsd.org -Date: Thu Jul 27 22:26:49 2023 +0000 - - upstream: don't incorrectly truncate logged strings retrieved from - - PKCS#11 modules; based on GHPR406 by Jakub Jelen; ok markus - - OpenBSD-Commit-ID: 7ed1082f23a13b38c373008f856fd301d50012f9 - -commit d1ffde6b55170cd4b9a72bfd9a3f17508e6cf714 -Author: djm@openbsd.org -Date: Thu Jul 27 22:25:17 2023 +0000 - - upstream: make sshd_config AuthorizedPrincipalsCommand and - - AuthorizedKeysCommand accept the %D (routing domain) and a new %C (connection - address/port 4-tuple) as expansion sequences; ok markus - - OpenBSD-Commit-ID: ee9a48bf1a74c4ace71b69de69cfdaa2a7388565 - -commit 999a2886ca1844a7a74b905e5f2c8c701f9838cd -Author: djm@openbsd.org -Date: Thu Jul 27 22:23:05 2023 +0000 - - upstream: increase default KDF work-factor for OpenSSH format - - private keys from 16 to 24; { feedback ok } x { deraadt markus } - - OpenBSD-Commit-ID: a3afb1383f8ff0a49613d449f02395d9e8d4a9ec - -commit 0fa803a1dd1c7b546c166000e23a869cf6c4ec10 -Author: Darren Tucker -Date: Thu Jul 27 02:25:09 2023 +1000 - - Prefer OpenSSL's SHA256 in sk-dummy.so - - Previously sk-dummy.so used libc's (or compat's) SHA256 since it may be - built without OpenSSL. In many cases, however, including both libc's - and OpenSSL's headers together caused conflicting definitions. - - We tried working around this (on OpenSSL <1.1 you could define - OPENSSL_NO_SHA, NetBSD had USE_LIBC_SHA2, various #define hacks) with - varying levels of success. Since OpenSSL >=1.1 removed OPENSSL_NO_SHA - and including most OpenSSL headers would bring sha.h in, even if it - wasn't used directly this was a constant hassle. - - Admit defeat and use OpenSSL's SHA256 unless we aren't using OpenSSL at - all. ok djm@ - -commit 36cdb5dbf55c99c0faad06066f56a7c341258c1f -Author: Darren Tucker -Date: Thu Jul 27 10:29:44 2023 +1000 - - Retire dfly58 test VM. Add dfly64. - -commit 2d34205dab08ede9b0676efa57647fc49e6decbe -Author: djm@openbsd.org -Date: Wed Jul 26 23:06:00 2023 +0000 - - upstream: make ssh -f (fork after authentication) work properly in - - multiplexed cases (inc. ControlPersist). bz3589 bz3589 Based on patches by - Peter Chubb; ok dtucker@ - - OpenBSD-Commit-ID: a7a2976a54b93e6767dc846b85647e6ec26969ac - -commit 076aeda86a7ee9be8fd2f0181ec7b9729a6ceb37 -Author: naddy@openbsd.org -Date: Sun Jul 23 20:04:45 2023 +0000 - - upstream: man page typos; ok jmc@ - - OpenBSD-Commit-ID: e6ddfef94b0eb867ad88abe07cedc8ed581c07f0 - -commit 135e7d5fe31f700e6dfc61ce914970c5ee7175ba -Author: jmc@openbsd.org -Date: Thu Jul 20 05:43:39 2023 +0000 - - upstream: tweak the allow-remote-pkcs11 text; - - OpenBSD-Commit-ID: bc965460a89edf76865b7279b45cf9cbdebd558a - -commit 5f83342b61d1f76c141de608ed2bd293990416bd -Author: Darren Tucker -Date: Tue Jul 25 13:00:22 2023 +1000 - - Handle a couple more OpenSSL no-ecc cases. - - ok djm@ - -commit edc2ef4e418e514c99701451fae4428ec04ce538 -Author: Damien Miller -Date: Thu Jul 20 12:53:44 2023 +1000 - - depend - -commit 51fda734e0d3c2df256fc03e8b060c4305be6e59 -Author: Damien Miller -Date: Thu Jul 20 12:53:21 2023 +1000 - - Bring back OPENSSL_HAS_ECC to ssh-pkcs11-client - -commit 099cdf59ce1e72f55d421c8445bf6321b3004755 -Author: djm@openbsd.org -Date: Wed Jul 19 14:03:45 2023 +0000 - - upstream: Separate ssh-pkcs11-helpers for each p11 module - - Make ssh-pkcs11-client start an independent helper for each provider, - providing better isolation between modules and reliability if a single - module misbehaves. - - This also implements reference counting of PKCS#11-hosted keys, - allowing ssh-pkcs11-helper subprocesses to be automatically reaped - when no remaining keys reference them. This fixes some bugs we have - that make PKCS11 keys unusable after they have been deleted, e.g. - https://bugzilla.mindrot.org/show_bug.cgi?id=3125 - - ok markus@ - - OpenBSD-Commit-ID: 0ce188b14fe271ab0568f4500070d96c5657244e - -commit 29ef8a04866ca14688d5b7fed7b8b9deab851f77 -Author: djm@openbsd.org -Date: Wed Jul 19 14:02:27 2023 +0000 - - upstream: Ensure FIDO/PKCS11 libraries contain expected symbols - - This checks via nlist(3) that candidate provider libraries contain one - of the symbols that we will require prior to dlopen(), which can cause - a number of side effects, including execution of constructors. - - Feedback deraadt; ok markus - - OpenBSD-Commit-ID: 1508a5fbd74e329e69a55b56c453c292029aefbe - -commit 1f2731f5d7a8f8a8385c6031667ed29072c0d92a -Author: djm@openbsd.org -Date: Wed Jul 19 13:56:33 2023 +0000 - - upstream: Disallow remote addition of FIDO/PKCS11 provider - - libraries to ssh-agent by default. - - The old behaviour of allowing remote clients from loading providers - can be restored using `ssh-agent -O allow-remote-pkcs11`. - - Detection of local/remote clients requires a ssh(1) that supports - the `session-bind@openssh.com` extension. Forwarding access to a - ssh-agent socket using non-OpenSSH tools may circumvent this control. - - ok markus@ - - OpenBSD-Commit-ID: 4c2bdf79b214ae7e60cc8c39a45501344fa7bd7c - -commit 892506b13654301f69f9545f48213fc210e5c5cc -Author: djm@openbsd.org -Date: Wed Jul 19 13:55:53 2023 +0000 - - upstream: terminate process if requested to load a PKCS#11 provider - - that isn't a PKCS#11 provider; from / ok markus@ - - OpenBSD-Commit-ID: 39532cf18b115881bb4cfaee32084497aadfa05c - -commit f3f56df8ec476b2de6cbdbdfdb77a2a61087829d -Author: Damien Miller -Date: Wed Jul 19 12:07:18 2023 +1000 - - agent_fuzz doesn't want stdint.h conditionalised - -commit 750911fd31d307a767cc86e3bfa90bbbb77b1a25 -Author: Damien Miller -Date: Tue Jul 18 15:41:12 2023 +1000 - - conditionalise stdint.h inclusion on HAVE_STDINT_H - - fixes build on AIX5 at least - -commit ff047504fa6e008c4092f8929881816b8993bea0 -Author: Damien Miller -Date: Tue Jul 18 15:30:45 2023 +1000 - - conditionalise match localnetwork on ifaddrs.h - - Fixes build breakage on platforms that lack getifaddrs() - -commit b87b03282e466ca2927954ce93f5dbf0bfdc68f6 -Author: djm@openbsd.org -Date: Mon Jul 17 06:16:33 2023 +0000 - - upstream: missing match localnetwork negation check - - OpenBSD-Commit-ID: 9a08ed8dae27d3f38cf280f1b28d4e0ff41a737a - -commit 6d6e185ba29ef4274164b77eab4dc763907f8821 -Author: jmc@openbsd.org -Date: Mon Jul 17 05:41:53 2023 +0000 - - upstream: - add -P to usage() - sync the arg name to -J in usage() - - with that in ssh.1 - reformat usage() to match what "man ssh" does on 80width - - OpenBSD-Commit-ID: 5235dd7aa42e5bf90ae54579d519f92fc107036e - -commit f1a9898283a0638667b587ee4a950afd61ab51b0 -Author: jmc@openbsd.org -Date: Mon Jul 17 05:38:10 2023 +0000 - - upstream: -P before -p in SYNOPSIS; - - OpenBSD-Commit-ID: 535f5257c779e26c6a662a038d241b017f8cab7c - -commit eef4d7e873568e1c84c36bb4034e2c3378250a61 -Author: jsg@openbsd.org -Date: Mon Jul 17 05:36:14 2023 +0000 - - upstream: configuation -> configuration - - OpenBSD-Commit-ID: 4776ced33b780f1db0b2902faec99312f26a726b - -commit dc1dbe94cf6532bd546a3373ad436404f8850e5f -Author: djm@openbsd.org -Date: Mon Jul 17 05:26:38 2023 +0000 - - upstream: move other RCSIDs to before their respective license blocks - - too no code change - - OpenBSD-Commit-ID: ef5bf46b57726e4260a63b032b0b5ac3b4fe9cd4 - -commit ebe11044681caff78834ca6b78311ad19c1860b8 -Author: djm@openbsd.org -Date: Mon Jul 17 05:22:30 2023 +0000 - - upstream: Move RCSID to before license block and away from #includes, - - where it caused merge conflict in -portable for each commit :( - - OpenBSD-Commit-ID: 756ebac963df3245258b962e88150ebab9d5fc20 - -commit 05c08e5f628de3ecf6f7ea20947735bcfa3201e0 -Author: djm@openbsd.org -Date: Mon Jul 17 05:20:15 2023 +0000 - - upstream: return SSH_ERR_KRL_BAD_MAGIC when a KRL doesn't contain a - - valid magic number and not SSH_ERR_MESSAGE_INCOMPLETE; the former is needed - to fall back to text revocation lists in some cases; fixes t-cert-hostkey. - - OpenBSD-Commit-ID: 5c670a6c0f027e99b7774ef29f18ba088549c7e1 - -commit c6fad2c3d19b74f0bd0af1ef040fc74f3a1d9ebb -Author: Damien Miller -Date: Mon Jul 17 14:56:14 2023 +1000 - - avoid AF_LINK on platforms that don't define it - -commit 919bc3d3b712c920de1ae6be5ac6561c98886d7e -Author: djm@openbsd.org -Date: Mon Jul 17 04:08:31 2023 +0000 - - upstream: Add support for configuration tags to ssh(1). - - This adds a ssh_config(5) "Tag" directive and corresponding - "Match tag" predicate that may be used to select blocks of - configuration similar to the pf.conf(5) keywords of the same - name. - - ok markus - - OpenBSD-Commit-ID: dc08358e70e702b59ac3e591827e5a96141b06a3 - -commit 3071d85a47061c1bdaf11a0ac233b501ecba862c -Author: djm@openbsd.org -Date: Mon Jul 17 04:04:36 2023 +0000 - - upstream: add a "match localnetwork" predicate. - - This allows matching on the addresses of available network interfaces - and may be used to vary the effective client configuration based on - network location (e.g. to use a ProxyJump when not on a particular - network). - - ok markus@ - - OpenBSD-Commit-ID: cffb6ff9a3803abfc52b5cad0aa190c5e424c139 - -commit beec17bb311365b75a0a5941418d4b96df7d7888 -Author: djm@openbsd.org -Date: Mon Jul 17 04:01:10 2023 +0000 - - upstream: remove vestigal support for KRL signatures - - When the KRL format was originally defined, it included support for - signing of KRL objects. However, the code to sign KRLs and verify KRL - signatues was never completed in OpenSSH. - - Now, some years later, we have SSHSIG support in ssh-keygen that is - more general, well tested and actually works. So this removes the - semi-finished KRL signing/verification support from OpenSSH and - refactors the remaining code to realise the benefit - primarily, we - no longer need to perform multiple parsing passes over KRL objects. - - ok markus@ - - OpenBSD-Commit-ID: 517437bab3d8180f695c775410c052340e038804 - -commit 449566f64c21b4578d5c0c431badd0328adc53ed -Author: djm@openbsd.org -Date: Mon Jul 17 03:57:21 2023 +0000 - - upstream: Support for KRL extensions. - - This defines wire formats for optional KRL extensions and implements - parsing of the new submessages. No actual extensions are supported at - this point. - - ok markus - - OpenBSD-Commit-ID: ae2fcde9a22a9ba7f765bd4f36b3f5901d8c3fa7 - -commit 18ea857770e84825a3a6238bb37f54864487b59f -Author: dtucker@openbsd.org -Date: Fri Jul 14 07:44:21 2023 +0000 - - upstream: Include stdint.h for SIZE_MAX. Fixes OPENSSL=no build. - - OpenBSD-Commit-ID: e7c31034a5434f2ead3579b13a7892960651e6b0 - -commit 20b768fcd13effe0f2d3619661b6c8592c773553 -Author: Darren Tucker -Date: Fri Jul 14 17:07:32 2023 +1000 - - Fix typo in declaration of nmesg. - -commit 4b94d09542e36ebde2eb9ad89bc68431609932de -Author: Damien Miller -Date: Fri Jul 14 15:34:47 2023 +1000 - - portable-specific int overflow defence-in-depth - - These too are unreachable, but we want the code to be safe regardless of - context. Reported by Yair Mizrahi @ JFrog - -commit 2ee48adb9fc8692e8d6ac679dcc9f35e89ad68f0 -Author: djm@openbsd.org -Date: Fri Jul 14 05:31:44 2023 +0000 - - upstream: add defence-in-depth checks for some unreachable integer - - overflows reported by Yair Mizrahi @ JFrog; feedback/ok millert@ - - OpenBSD-Commit-ID: 52af085f4e7ef9f9d8423d8c1840a6a88bda90bd - -commit 4b43bc358ae6f6b19a973679246dc5172f6ac41b -Author: djm@openbsd.org -Date: Mon Jul 10 04:51:26 2023 +0000 - - upstream: misplaced debug message - - OpenBSD-Commit-ID: d0f12af0a5067a756aa707bc39a83fa6f58bf7e5 - -commit 8c7203bcee4c4f98a22487b4631fe068b992099b -Author: Damien Miller -Date: Wed Jul 12 11:41:19 2023 +1000 - - replace deprecate selinux matchpathcon function - - This function is apparently deprecated. Documentation on what is the - supposed replacement is is non-existent, so this follows the approach - glibc used https://sourceware.org/git/?p=glibc.git;a=patch;h=f278835f59 - - ok dtucker@ - -commit 7e8800f5d701efffa39ccb63ca1e095ea777c31a -Author: dtucker@openbsd.org -Date: Thu Jul 6 22:17:59 2023 +0000 - - upstream: minleft and maxsign are u_int so cast appropriately. Prompted - - by github PR#410, ok deraadt. - - OpenBSD-Commit-ID: 0514cd51db3ec60239966622a0d3495b15406ddd - -commit 94842bfe9b09fc93189c6ed0dc9bbebc1d44a426 -Author: dlg@openbsd.org -Date: Tue Jul 4 03:59:21 2023 +0000 - - upstream: add support for unix domain sockets to ssh -W - - ok djm@ dtucker@ - - OpenBSD-Commit-ID: 3e6d47567b895c7c28855c7bd614e106c987a6d8 - -commit a95fc5eed09a0238fb127b6c50e8498432b79dae -Author: David Seifert -Date: Fri May 12 14:06:01 2023 +0200 - - gss-serv.c: `MAXHOSTNAMELEN` -> `HOST_NAME_MAX` - - `MAXHOSTNAMELEN` is not defined in POSIX, which breaks on musl: - https://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html - - Bug: https://bugs.gentoo.org/834044 - -commit 8a6cd08850f576e7527c52a1b086cae82fab290e -Author: Darren Tucker -Date: Fri Jun 23 09:49:02 2023 +1000 - - Update runner OS version for hardenedmalloc test. - - Hardenedmalloc dropped support for "legacy glibc" versions in their - 64dad0a69 so use a newer Ubuntu version for the runner for that test. - -commit cfca6f17e64baed6822bb927ed9f372ce64d9c5b -Author: Damien Miller -Date: Thu Jun 22 15:04:03 2023 +1000 - - handle sysconf(SC_OPEN_MAX) returning > INT_MAX; - - bz3581; ok dtucker - -commit c1c2ca1365b3f7b626683690bd2c68265f6d8ffd -Author: djm@openbsd.org -Date: Wed Jun 21 05:10:26 2023 +0000 - - upstream: better validate CASignatureAlgorithms in ssh_config and - - sshd_config. - - Previously this directive would accept certificate algorithm names, but - these were unusable in practice as OpenSSH does not support CA chains. - - part of bz3577; ok dtucker@ - - OpenBSD-Commit-ID: a992d410c8a78ec982701bc3f91043dbdb359912 - -commit 4e73cd0f4ab3e5b576c56cac9732da62c8fc0565 -Author: djm@openbsd.org -Date: Wed Jun 21 05:08:32 2023 +0000 - - upstream: make `ssh -Q CASignatureAlgorithms` only list signature - - algorithms that are valid for CA signing. Previous behaviour was to list all - signing algorithms, including certificate algorithms (OpenSSH certificates do - not support CA chains). part of bz3577; ok dtucker@ - - OpenBSD-Commit-ID: 99c2b072dbac0f44fd1f2269e3ff6c1b5d7d3e59 - -commit a69062f1695ac9c3c3dea29d3044c72aaa6af0ea -Author: djm@openbsd.org -Date: Wed Jun 21 05:06:04 2023 +0000 - - upstream: handle rlimits > INT_MAX (rlim_t is u64); ok dtucker - - bz3581 - - OpenBSD-Commit-ID: 31cf59c041becc0e5ccb0a77106f812c4cd1cd74 - -commit 8d33f2aa6bb895a7f85a47189913639086347b75 -Author: djm@openbsd.org -Date: Tue Jun 20 23:59:33 2023 +0000 - - upstream: prepare for support for connecting to unix domain sockets - - using ssh -W by explicitly decoding PORT_STREAMLOCAL (a negative number) from - the u32 that's passed over the multiplexing socket; previously code would - just cast, which is UB. - - OpenBSD-Commit-ID: e5ac5f40d354096c51e8c118a5c1b2d2b7a31384 - -commit b4ac435b4e67f8eb5932d8f59eb5b3cf7dc38df0 -Author: djm@openbsd.org -Date: Tue Jun 20 00:05:09 2023 +0000 - - upstream: reset comment=NULL for each key in do_fingerprint(); - - fixes "no comment" not showing on when running `ssh-keygen -l` on multiple - keys where one has a comment and other following keys do not. Patch from - Markus Kuhn via GHPR407, bz3580 - - OpenBSD-Commit-ID: 3cce84456fdcd67dc6b84e369f92c6686d111d9b - -commit b53a809a549dcd4fbde554c6aa283e597b15ea33 -Author: millert@openbsd.org -Date: Mon Jun 5 13:24:36 2023 +0000 - - upstream: Store timeouts as int, not u_int as they are limited to - - INT_MAX. Fixes sign compare warnings systems with 32-bit time_t due to type - promotion. OK djm@ - - OpenBSD-Commit-ID: 48081e9ad35705c5f1705711704a4c2ff94e87b7 - -commit 2709809fd616a0991dc18e3a58dea10fb383c3f0 -Author: Philip Hands -Date: Wed May 24 19:41:14 2023 +0200 - - fixup! if -s & -p specified, mention 'sftp -P' on - - success - - SSH-Copy-ID-Upstream: 32686e7c65b4fa2846e474d3315102dfa0f043b0 - -commit 204e0bf05161b7641500d7ab266c21217412379f -Author: Darren Tucker -Date: Tue Aug 3 21:25:48 2021 +1000 - - Make ssh-copy-id(1) consistent with OpenSSH. - - This makes the ssh-copy-id man page more consistent with the rest of the - OpenSSH man pages: - - new sentence, new line - - no sentences >80 - - N.B. -> NB - - zap unused .Pp - - zap trailing whitespace - - Report from Debian via mindrot bz#3331, diff from jmc at openbsd.org. - - SSH-Copy-ID-Upstream: d8974cfb6242316460ed22a1ccc662800a50c5d3 - -commit 9de79df66d1430d290fab670bb4b18612875e518 -Author: Philip Hands -Date: Wed May 24 11:45:43 2023 +0200 - - if -s & -p specified, mention 'sftp -P' on success - - This was inspired by this: - https://github.com/openssh/openssh-portable/pull/321 - but I thought that it was better to not do the sed patching. - - BTW the reason one can get away with using $SSH_OPTS throughout, despite - the lowercase -p in there, even if sftp is in use, is that the sftp call - is using the already-established ssh master connection, so the port was - passed to the earlier ssh. - - SSH-Copy-ID-Upstream: 1c124d9bfafdbe28a00b683367ebf5750ce12eb2 - -commit 801cda54c00e0f4e7d89345a90874c8d05dc233a -Author: Philip Hands -Date: Tue May 23 23:07:11 2023 +0200 - - drop whitespace - - SSH-Copy-ID-Upstream: e604fae1cdee35c18055d35dcec530cf12ef00ad - -commit 288482f53613f3e74544eb92deeb24f7c7f1f371 -Author: Philip Hands -Date: Tue May 23 20:52:13 2023 +0200 - - make -x also apply to the target script - - SSH-Copy-ID-Upstream: 3c4214704f427bd0654adf9b0fc079253db21cf4 - -commit b79e7b88ed44f0e4339f0ff35c96c78a92175a8d -Author: Philip Hands -Date: Tue May 23 16:46:42 2023 +0200 - - add -t option to specify the target path - - Allow the default target path (.ssh/authorized_files) to be over-riden - - This was inspired by this MR from Panagiotis Cheilaris - - https://gitlab.com/phil_hands/ssh-copy-id/-/merge_requests/8 - - SSH-Copy-ID-Upstream: a942a0e076874adb6d8b2f0fb76d6c7918190fcd - -commit 914f4ad138714c471ba72fb6d5496b6235320edd -Author: Carlos Rodríguez Gili -Date: Tue Apr 20 19:23:57 2021 +0200 - - Fix test error for /bin/sh on Solaris 10 and older - - On Solaris 10 and older targets /bin/sh is not POSIX-compliant. - Test -z `...` fails with error 'sh: test: argument expected'. - Using quotes around backticks fixes this and doesn't break - POSIX compatibility. - - SSH-Copy-ID-Upstream: 98394072a3f985b2650c1e8eab2fef84e38cc065 - -commit bd382dca316c721aed1e45edcf4c4e0f6374afb0 -Author: Jakub Jelen -Date: Tue Mar 2 21:34:05 2021 +0000 - - Remove outdated comment - - The commit b068122 removed the code dropping the trailing colon, but the comment stayed leaving the code confusing for future readers - - SSH-Copy-ID-Upstream: 930d39f238117cd53810240ec989d0356aa1c1f6 - -commit bdcaf7939029433635d63aade8f9ac762aca2bbe -Author: Darren Tucker -Date: Wed May 10 18:50:46 2023 +1000 - - Special case OpenWrt instead of Dropbear. - - OpenWrt overrides the location of authorized_keys for root. Currently we - assume that all Dropbear installations behave this way, which is not the - case. Check for OpenWrt and root user before using that location instead - of assuming that for all Dropbear servers. Prompted by Github PR#250. - - SSH-Copy-ID-Upstream: 0e1f5d443a9967483c33945793107ae3f3e4af2d - -commit cf84498f67abe93f813a296167b406a0db7b288e -Author: Philip Hands -Date: Thu May 18 18:20:55 2023 +0200 +commit a68f80f2511f0e0c5cef737a8284cc2dfabad818 +Author: anton@openbsd.org +Date: Wed Apr 3 06:01:11 2024 +0000 - ssh-copy-id: add -x option (for debugging) - - This option causes the ssh-copy-id to run with set -x + upstream: Since ssh-agent(1) is only readable by root by now, use - SSH-Copy-ID-Upstream: a0ee367ea8c0a29c8b4515245e408d2d349e7844 - -commit b4a1efdcb88f03394c08e7f68ed4e11676830002 -Author: Philip Hands -Date: Thu May 18 17:14:41 2023 +0200 - - update copyright notices + ssh(1) while generating data in tests. - SSH-Copy-ID-Upstream: c284ed33b361814ea48ff68cbd01ca525b2bf117 + OpenBSD-Regress-ID: 24eb40de2e6b0ace185caaba35e2d470331ffe68 -commit fcd78e31cdd45a7e69ccfe6d8a3b1037dc1de290 +commit 92e55890314ce2b0be21a43ebcbc043b4abc232f Author: djm@openbsd.org -Date: Wed May 24 23:01:06 2023 +0000 - - upstream: fix AuthorizedPrincipalsCommand when AuthorizedKeysCommand - - appears previously in configuration. Reported by John Meyers in bz3574 ok - dtucker@ - - OpenBSD-Commit-ID: 1c92e4517284386703936e1d3abaa36cfacf1951 - -commit 5ec5504f1d328d5bfa64280cd617c3efec4f78f3 -Author: dtucker@openbsd.org -Date: Wed May 10 10:04:20 2023 +0000 +Date: Fri May 17 01:17:40 2024 +0000 - upstream: Remove unused prototypes for ssh1 RSA functions. - - From lengyijun via github PR#396. + upstream: fix incorrect debug option name introduce in previous - OpenBSD-Commit-ID: 379a5afa8b7a0f3cba0c8a9bcceb4e5e33a5c1ef - -commit fbf362b3891ae4b36052d1b39f37fc618b41c476 -Author: Darren Tucker -Date: Tue May 9 19:26:56 2023 +1000 - - main(void) to prevent unused variable warning. - -commit baf854c8bb0a6d0af5c696c801e631a48dabbaba -Author: Darren Tucker -Date: Tue May 9 19:25:45 2023 +1000 - - Remove warning pragma since clang doesn't like it. - -commit 5fbb7a1349fbbb48ccb1b8cafff2c1854370d87d -Author: Darren Tucker -Date: Tue May 9 17:13:33 2023 +1000 - - Suppress warning for snprintf truncation test. - -commit 47742c513e4e045ecc985c6483fc5c8b050acda2 -Author: Darren Tucker -Date: Tue May 9 17:12:50 2023 +1000 - - Update OpenSSL compat test for 3.x. - -commit 86ad25d455a2313126125540e61e0f9314283f88 -Author: Darren Tucker -Date: Mon May 8 20:23:08 2023 +1000 - - Add macos13 PAM test target. - -commit 77cca2c4b13bc6e5f389565583b6202b0d1bccc2 -Author: Darren Tucker -Date: Mon May 8 20:14:46 2023 +1000 - - Skip agent-peereid test on macos13. + commit - sudo -S nobody doesn't work on the github runners (probably a - permission issue) so skip that test. - -commit b356b8e91678ea295bcf44df5248c3fbf499fdcf -Author: Darren Tucker -Date: Mon May 8 20:14:28 2023 +1000 - - Include config.guess in debug output. + OpenBSD-Commit-ID: 66d69e22b1c072c694a7267c847f212284614ed3 -commit b7afd8a4ecaca8afd3179b55e9db79c0ff210237 -Author: Darren Tucker -Date: Mon May 8 20:12:59 2023 +1000 +commit 4ad72878af7b6ec28da6e230e36a91650ebe84c1 +Author: deraadt@openbsd.org +Date: Fri May 17 00:33:25 2024 +0000 - Handle OpenSSL >=3 ABI compatibility. + upstream: construct and install a relink-kit for sshd-session ok - Beyond OpenSSL 3.0, the ABI compatibility guarantees are wider (only - major must match instead of major and minor in earlier versions). - bz#3548, ok djm@ - -commit 0e9e2663eb2c6e9c3e10d15d70418312ae67e542 -Author: dtucker@openbsd.org -Date: Mon May 1 08:57:29 2023 +0000 - - upstream: Import regenerated moduli. + djm - OpenBSD-Commit-ID: 3d5f811cfcaed8cc4a97e1db49ac61bdf118113c + OpenBSD-Commit-ID: 8b3820adb4da4e139c4b3cffbcc0bde9f08bf0c6 -commit d9687f49682e1e93383fc15ab2018850b2ef38c3 -Author: Darren Tucker -Date: Mon May 1 11:45:14 2023 +1000 +commit 02e679a2cb3f6df8e9dbb1519ed578226485157f +Author: Damien Miller +Date: Fri May 17 12:21:27 2024 +1000 - Add macos-13 test target. - - Also flatten OS list for clarity. + Makefile support for sshd-session -commit aacfd6767497b8fa6d41ecdd3f8e265d1e9ef1f6 +commit c0416035c5eaf70a8450d11c8833c5f7068ee7ad Author: djm@openbsd.org -Date: Sun Apr 30 22:54:22 2023 +0000 +Date: Fri May 17 00:32:32 2024 +0000 - upstream: adjust ftruncate() logic to handle servers that reorder - - requests. - - sftp/scp will ftruncate the destination file after a transfer completes, - to deal with the case where a longer destination file already existed. - We tracked the highest contiguous block transferred to deal with this - case, but our naive tracking doesn't deal with servers that reorder - requests - a misfeature strictly permitted by the protocol but seldom - implemented. - - Adjust the logic to ftruncate() at the highest absolute block received - when the transfer is successful. feedback deraadt@ ok markus@ - - prompted by https://github.com/openssh/openssh-portable/commit/9b733#commitcomment-110679778 + upstream: missing files from previous - OpenBSD-Commit-ID: 4af7fac75958ad8507b4fea58706f3ff0cfddb1b + OpenBSD-Commit-ID: 4b7be4434d8799f02365552b641a7a70a7ebeb2f -commit c8eb3941758615c8284a48fff47872db926da63c +commit 03e3de416ed7c34faeb692967737be4a7bbe2eb5 Author: djm@openbsd.org -Date: Wed Apr 26 01:36:03 2023 +0000 - - upstream: Check for ProxyJump=none in CanonicalizeHostname logic. - - Previously ssh would incorrectly refuse to canonicalise the hostname - if ProxyJump was explicitly set to "none" when CanonicalizeHostname=yes - - bz3567; ok dtucker - - OpenBSD-Commit-ID: 80a58e43c3a32f97361282f756ec8d3f37989efd - -commit ac383f3a5c6f529a2e8a5bc44af79a08c7da294e -Author: jsg@openbsd.org -Date: Wed Apr 12 14:22:04 2023 +0000 +Date: Fri May 17 00:30:23 2024 +0000 - upstream: remove duplicate signal.h include + upstream: Start the process of splitting sshd into separate - OpenBSD-Commit-ID: 30c0a34d74d91ddd0e6992525da70d3293392f70 - -commit 740dafa20f3f3d325f6f5d44e990b8c8a6d3d816 -Author: jsg@openbsd.org -Date: Wed Apr 12 08:53:54 2023 +0000 - - upstream: fix double words ok dtucker@ + binaries. This step splits sshd into a listener and a session binary. More + splits are planned. - OpenBSD-Commit-ID: 44d3223902fbce5276422bdc8063ab72a4078489 - -commit 6452f89577ec4f22440c31b8e19b061d1a7c4b2a -Author: Darren Tucker -Date: Tue Apr 11 16:49:19 2023 +1000 - - Test against LibreSSL 3.7.2. - -commit 2138f6be595ca106fe4805a1e3ab9c4d8acc697b -Author: Damien Miller -Date: Thu Apr 6 14:33:10 2023 +1000 - - remove unused upper-case const strings in fmtfp + After this changes, the listener binary will validate the configuration, + load the hostkeys, listen on port 22 and manage MaxStartups only. All + session handling will be performed by a new sshd-session binary that the + listener fork+execs. - no float format that uses upper-case is supported nor are hex floats. - ok dtucker - -commit 484c5e6168fdb22cbcd73c4ff987cf9ca47989ca -Author: djm@openbsd.org -Date: Thu Apr 6 03:56:02 2023 +0000 - - upstream: simplify sshsig_find_principals() similar to what happened to + This reduces the listener process to the minimum necessary and sets us + up for future work on the sshd-session binary. + + feedback/ok markus@ deraadt@ - sshsig_check_allowed_keys() in r1.31, removing some dead code + NB. if you're updating via source, please restart sshd after installing, + otherwise you run the risk of locking yourself out. - OpenBSD-Commit-ID: a493e628d4d6c08f878c276d998f4313ba61702d + OpenBSD-Commit-ID: 43c04a1ab96cdbdeb53d2df0125a6d42c5f19934 -commit 3a7b110fbc7e096423f8f7b459deffe4c65d70f4 +commit 1c0d81357921f8d3bab06841df649edac515ae5b Author: djm@openbsd.org -Date: Thu Apr 6 03:21:31 2023 +0000 +Date: Thu May 9 09:46:47 2024 +0000 - upstream: remove redundant ssh!=NULL check; we'd already + upstream: simplify exit message handling, which was more complicated - dereferenced it + than it needed to be because of unexpunged ssh1 remnants. ok markus@ - OpenBSD-Commit-ID: 852bf12591ec5a9fb12dcbde9b1fd3945ad0df3c + OpenBSD-Commit-ID: 8b0cd2c0dee75fb053718f442aa89510b684610b -commit 2519110659a1efac6c976895a86659d1b341c91b -Author: djm@openbsd.org -Date: Thu Apr 6 03:19:32 2023 +0000 +commit cbbbf76aa6cd54fce32eacce1300e7abcf9461d4 +Author: tobias@openbsd.org +Date: Mon May 6 19:26:17 2024 +0000 - upstream: match_user() shouldn't be called with user==NULL unless + upstream: remove SSH1 leftovers - host and ipaddr are also NULL + Authored with Space Meyer - OpenBSD-Commit-ID: fa3518346c21483e9e01a2e4b9436ae501daf8ea - -commit 3b9ceaad7ad63c1c03c2a89e148340ad3a62a482 -Author: djm@openbsd.org -Date: Thu Apr 6 03:12:32 2023 +0000 - - upstream: don't care about glob() return value here. + ok djm - OpenBSD-Commit-ID: 85bb82fea90478a482e9f65a1bec0aa24227fd66 + OpenBSD-Commit-ID: 81db602e4cb407baae472689db1c222ed7b2afa3 -commit 09d8da0849e2791b2500267cda333cd238f38754 -Author: dtucker@openbsd.org -Date: Mon Apr 3 08:10:54 2023 +0000 +commit bc5dcb8ab9a4e8af54a724883732af378f42ea78 +Author: tobias@openbsd.org +Date: Tue Apr 30 15:40:43 2024 +0000 - upstream: Move up null check and simplify process_escapes. + upstream: never close stdin - Based on Coverity CID 291863 which points out we check the channel - pointer for NULLness after dereferencing it. Move this to the start - of the function, and while there simplify initialization of efc a bit. - ok djm@ + The sanitise_stdfd call makes sure that standard file descriptors are + open (if they were closed, they are connected with /dev/null). - OpenBSD-Commit-ID: de36e5ad6fde0fe263ca134e986b9095dc59380a - -commit b36b162be5e6206f12b734222b7bc517c13a6bc8 -Author: Damien Miller -Date: Fri Mar 31 14:51:20 2023 +1100 - - need va_end() after va_copy(); ok dtucker + Do not close stdin in any case to prevent error messages when stdin is + read multiple times and to prevent later usage of fd 0 for connections, + e.g. - spotted by Coverity - -commit f703757234a5c585553e72bba279b255a272750a -Author: dtucker@openbsd.org -Date: Fri Mar 31 05:56:36 2023 +0000 - - upstream: Explicitly ignore return from waitpid here too. + echo localhost | ssh-keyscan -f - -f - - OpenBSD-Commit-ID: eef2403df083c61028969fc679ee370373eacacb - -commit 6b73aa29035991d1448a1a76f63ac152a6bf931c -Author: dtucker@openbsd.org -Date: Fri Mar 31 04:45:08 2023 +0000 - - upstream: Explictly ignore return codes + While at it, make stdin-related error messages nicer. + + Authored with Max Kunzelmann - where we don't check them. + ok djm - OpenBSD-Commit-ID: 1ffb03038ba1b6b72667be50cf5e5e396b5f2740 + OpenBSD-Commit-ID: 48e9b7938e2fa2f9bd47e6de6df66a31e0b375d3 -commit 6f0308a3e717ebe68eeb3f95253612fab5dbf20e -Author: dtucker@openbsd.org -Date: Fri Mar 31 04:42:29 2023 +0000 +commit 6a42b70e56bef1aacdcdf06352396e837883e84f +Author: Damien Miller +Date: Wed May 8 09:43:59 2024 +1000 - upstream: Return immediately from get_sock_port - - if sock <0 so we don't call getsockname on a negative FD. From Coverity - CID 291840, ok djm@ - - OpenBSD-Commit-ID: de1c1130646230c2eda559831fc6bfd1b61d9618 + sync getrrsetbyname.c with recent upstream changes -commit 1c1124dc901fca1ea2cb762044b8f1a5793a2bed +commit 385ecb31e147dfea59c1c488a1d2011d3867e60e Author: djm@openbsd.org -Date: Fri Mar 31 04:23:02 2023 +0000 +Date: Tue Apr 30 06:23:51 2024 +0000 - upstream: don't leak arg2 on parse_pubkey_algos error path; ok + upstream: fix home-directory extension implementation, it always - dtucker@ + returned the current user's home directory contrary to the spec. - OpenBSD-Commit-ID: 7d0270ad3dd102412ca76add2b3760518abdef75 - -commit 8ba2d4764bb6a4701cd447d8b52604622ffe65f4 -Author: djm@openbsd.org -Date: Fri Mar 31 04:22:27 2023 +0000 - - upstream: clamp max number of GSSAPI mechanisms to 2048; ok dtucker + Patch from Jakub Jelen via GHPR477 - OpenBSD-Commit-ID: ce66db603a913d3dd57063e330cb5494d70722c4 + OpenBSD-Commit-ID: 5afd775eab7f9cbe222d7fbae4c793de6c3b3d28 -commit 1883841fc13d0eada8743cac5d3abe142ee2efa7 +commit 14e2b16bc67ffcc188906f65008667e22f73d103 Author: djm@openbsd.org -Date: Fri Mar 31 04:21:56 2023 +0000 +Date: Tue Apr 30 06:16:55 2024 +0000 - upstream: don't print key if printing hostname failed; with/ok + upstream: flush stdout after writing "sftp>" prompt when not using - dtucker@ + editline. - OpenBSD-Commit-ID: ad42971a6ee5a46feab2d79f7f656f8cf4b119f3 - -commit c6011129cafe4c411f6ef670a4cf271314708eb8 -Author: djm@openbsd.org -Date: Fri Mar 31 04:04:15 2023 +0000 - - upstream: remove redundant test + From Alpine Linux via GHPR480 - OpenBSD-Commit-ID: 6a0b719f9b1ae9d42ad8c5b144c7962c93792f7c + OpenBSD-Commit-ID: 80bdc7ffe0358dc090eb9b93e6dedb2b087b24cd -commit 4fb29eeafb40a2076c0dbe54e46b687c318f87aa +commit 2e69a724051488e3fb3cd11531c4b5bc1764945b Author: djm@openbsd.org -Date: Fri Mar 31 04:00:37 2023 +0000 +Date: Tue Apr 30 05:53:03 2024 +0000 - upstream: don't attempt to decode a ridiculous number of + upstream: stricter validation of messaging socket fd number; disallow - attributes; harmless because of bounds elsewhere, but better to be explicit + usage of stderr. Based on GHPR492 by RealHurrison - OpenBSD-Commit-ID: 1a34f4b6896155b80327d15dc7ccf294b538a9f2 + OpenBSD-Commit-ID: 73dbbe82ea16f73ce1d044d3232bc869ae2f2ce8 -commit fc437c154ef724621a4af236de9bc7e51a8381ae +commit da757b022bf18c6f7d04e685a10cd96ed00f83da Author: djm@openbsd.org -Date: Fri Mar 31 03:22:49 2023 +0000 - - upstream: remove unused variable; prompted by Coverity CID 291879 - - OpenBSD-Commit-ID: 4c7d20ef776887b0ba1aabcfc1b14690e4ad0a40 - -commit 0eb8131e4a53b33a8fc9b9ab694e6b6778b87ade -Author: dtucker@openbsd.org -Date: Fri Mar 31 00:44:29 2023 +0000 +Date: Tue Apr 30 05:45:56 2024 +0000 - upstream: Check fd against >=0 instead of >0 in error path. The - - dup could in theory return fd 0 although currently it doesn't in practice. - From Dmitry Belyavskiy vi github PR#238. + upstream: add missing reserved fields to key constraint protocol - OpenBSD-Commit-ID: 4a95f3f7330394dffee5c749d52713cbf3b54846 - -commit 7174ba6f8a431ca4257767a260fc50e204068242 -Author: dtucker@openbsd.org -Date: Thu Mar 30 07:19:50 2023 +0000 - - upstream: Ignore return value from muxclient(). It normally loops + documentation. - without returning, but it if returns on failure we immediately exit. - Coverity CID 405050. + from Wiktor Kwapisiewicz via GHPR487 - OpenBSD-Commit-ID: ab3fde6da384ea588226037c38635a6b2e015295 + OpenBSD-Commit-ID: 0dfb69998cfdb3fa00cbb0e7809e7d2f6126e3df -commit a4c1c2513e36f111eeaa1322c510067930e5e51e +commit 16d0b82fa08038f35f1b3630c70116979f49784f Author: Damien Miller -Date: Fri Mar 31 14:17:22 2023 +1100 +Date: Tue Apr 30 12:39:34 2024 +1000 - don't call connect() on negative socket - - Coverity CID 405037 + depend -commit 34ee842cdd981a759fe8f0d4a37521f9a1c63170 +commit 66aaa678dbe59aa21d0d9d89a3596ecedde0254b Author: djm@openbsd.org -Date: Thu Mar 30 03:05:01 2023 +0000 +Date: Tue Apr 30 02:14:10 2024 +0000 - upstream: return SSH_ERR_KEY_NOT_FOUND if the allowed_signers file + upstream: correctly restore sigprocmask around ppoll() reported - is empty, not SSH_ERR_INTERNAL_ERROR. Also remove some dead code spotted - by Coverity; with/ok dtucker@ + by Tõivo Leedjärv; ok deraadt@ - OpenBSD-Commit-ID: 898a1e817cda9869554b1f586a434f67bcc3b650 + OpenBSD-Commit-ID: c0c0f89de5294a166578f071eade2501929c4686 -commit f108e77a9dc9852e72215af1bf27731c48434557 -Author: dtucker@openbsd.org -Date: Thu Mar 30 00:49:37 2023 +0000 +commit 80fb0eb21551aed3aebb009ab20aeffeb01e44e0 +Author: djm@openbsd.org +Date: Tue Apr 30 02:10:49 2024 +0000 - upstream: Remove dead code from inside if block. + upstream: add explict check for server hostkey type against - The only way the if statement can be true is if both dup()s fail, and - in that case the tmp2 can never be set. Coverity CID 291805, ok djm@ + HostkeyAlgorithms. Allows HostkeyAlgorithms to disable implicit fallback from + certificate keys to plain keys. ok markus@ - OpenBSD-Commit-ID: c0d6089b3fb725015462040cd94e23237449f0c8 + OpenBSD-Commit-ID: 364087e4a395ff9b2f42bf3aefdb2090bb23643a -commit 05b8e88ebe23db690abbfb1a91111abea09cde08 -Author: Darren Tucker -Date: Thu Mar 30 13:53:29 2023 +1100 +commit 5b28096d31ff7d80748fc845553a4aef5bb05d86 +Author: jsg@openbsd.org +Date: Tue Apr 23 13:34:50 2024 +0000 - child_set_eng: verify both env pointer and count. + upstream: correct indentation; no functional change ok tb@ - If child_set env was called with a NULL env pointer and a non-zero count - it would end up in a null deref, although we don't currently do this. - Prompted by Coverity CID 291850, tweak & ok djm@ + OpenBSD-Commit-ID: dd9702fd43de546bc6a3f4f025c74d6f3692a0d4 -commit 28f1b8ef9b84b8cd2f6c9889a0c60aa4a90dadfa -Author: dtucker@openbsd.org -Date: Wed Mar 29 01:07:48 2023 +0000 +commit fd3cb8a82784e05f621dea5b56ac6f89bc53c067 +Author: semarie@openbsd.org +Date: Thu Apr 4 16:00:51 2024 +0000 - upstream: Ignore return from sshpkt_disconnect + upstream: set right mode on ssh-agent at boot-time - since we set our own return value for the function. Coverity CID 291797, - ok djm@ + which sthen@ + ok deraadt@ - OpenBSD-Commit-ID: 710b57ba954c139240895e23feea41f203201f04 + OpenBSD-Commit-ID: 662b5056a2c6171563e1626f9c69f27862b5e7af -commit c3da05d95922f5550bcc7815e799474d6a160175 -Author: dtucker@openbsd.org -Date: Wed Mar 29 00:59:08 2023 +0000 +commit 54343a260e3aa4bceca1852dde31cd08e2abd82b +Author: deraadt@openbsd.org +Date: Tue Apr 2 12:22:38 2024 +0000 - upstream: Plug potential mem leak in process_put. + upstream: Oops, incorrect hex conversion spotted by claudio. - It allocates abs_dst inside a loop but only frees it on exit, so free - inside the loop if necessary. Coverity CID 291837, ok djm@ + While here try to improve how it reads a bit better. Surprising the + regression tests didn't spot this error, maybe it fails to roundtrip the + values. - OpenBSD-Commit-ID: a01616503a185519b16f00dde25d34ceaf4ae1a3 + OpenBSD-Commit-ID: 866cfcc1955aef8f3fc32da0b70c353a1b859f2e -commit 13ae327eae598b1043e5ec30e4b170edb3c898a5 -Author: djm@openbsd.org -Date: Wed Mar 29 00:18:35 2023 +0000 +commit ec78c31409590ad74efc194f886273ed080a545a +Author: deraadt@openbsd.org +Date: Tue Apr 2 10:02:08 2024 +0000 - upstream: fix memory leak; Coverity CID 291848 + upstream: for parse_ipqos(), use strtonum() instead of mostly - with/ok dtucker@ + idiomatic strtoul(), but wow it's so gross. ok djm - OpenBSD-Commit-ID: 37f80cb5d075ead5a00ad1b74175684ab1156ff8 + OpenBSD-Commit-ID: cec14a76af2eb7b225300c80fc0e21052be67b05 -commit 9ffa76e1284c85bf459c3dcb8e995733a8967e1b -Author: dtucker@openbsd.org -Date: Tue Mar 28 07:44:32 2023 +0000 +commit 8176e1a6c2e6da9361a7abb6fbf6c23c299f495b +Author: deraadt@openbsd.org +Date: Tue Apr 2 09:56:58 2024 +0000 - upstream: Plug more mem leaks in sftp by making + upstream: can shortcut by returning strtonum() value directly; ok - make_absolute_pwd_glob work in the same way as make_absolute: you - pass it a dynamically allocated string and it either returns it, or - frees it and allocates a new one. Patch from emaste at freebsd.org and - https://reviews.freebsd.org/D37253 ok djm@ + djm - OpenBSD-Commit-ID: 85f7404e9d47fd28b222fbc412678f3361d2dffc + OpenBSD-Commit-ID: 7bb2dd3d6d1f288dac14247d1de446e3d7ba8b8e -commit 82b2b8326962b1a98af279bc5bbbbbcab15b3e45 -Author: dtucker@openbsd.org -Date: Tue Mar 28 06:12:38 2023 +0000 +commit 9f543d7022a781f80bb696f9d73f1d1c6f9e31d6 +Author: deraadt@openbsd.org +Date: Tue Apr 2 09:52:14 2024 +0000 - upstream: Remove compat code for OpenSSL < 1.1.* + upstream: rewrite convtime() to use a isdigit-scanner and - since -portable no longer supports them. + strtonum() instead of strange strtoul can might be fooled by garage + characters. passes regress/usr.bin/ssh/unittests/misc ok djm - OpenBSD-Commit-ID: ea2893783331947cd29a67612b4e56f818f185ff + OpenBSD-Commit-ID: 4b1ef826bb16047aea3f3bdcb385b72ffd450abc -commit b500afcf00ae1b6b73b2ccf171111dfbfeaef74d -Author: dtucker@openbsd.org -Date: Mon Mar 27 23:56:54 2023 +0000 +commit 8673137f780d8d9e4cda3c4605cb5d88d5cea271 +Author: claudio@openbsd.org +Date: Tue Apr 2 09:48:24 2024 +0000 - upstream: Remove compat code for OpenSSL 1.0.* + upstream: Remove unused ptr[3] char array in pkcs11_decode_hex. - versions now that -portable has dropped support for those versions. + OK deraadt@ - OpenBSD-Regress-ID: 82a8eacd87aec28e4aa19f17246ddde9d5ce7fe7 + OpenBSD-Commit-ID: 3d14433e39fd558f662d3b0431c4c555ef920481 -commit 727560e6011efcb36d2f3ac6910444bc775abaa1 -Author: Darren Tucker -Date: Tue Mar 28 18:06:42 2023 +1100 +commit c7fec708f331f108343d69e4d74c9a5d86d6cfe7 +Author: deraadt@openbsd.org +Date: Tue Apr 2 09:32:28 2024 +0000 - Prevent conflicts between Solaris SHA2 and OpenSSL. + upstream: Replace non-idiomatic strtoul(, 16) to parse a region - We used to prevent conflicts between native SHA2 headers and OpenSSL's - by setting OPENSSL_NO_SHA but that was removed prior to OpenSSL 1.1.0 - -commit 46db8e14b7f186d32173dcdecd5b785334429b8b -Author: Darren Tucker -Date: Tue Mar 28 12:44:03 2023 +1100 - - Remove HEADER_SHA_H from previous... + of 2-character hex sequences with a low-level replacement designed just for + the task. ok djm - since it causes more problems than it solves. + OpenBSD-Commit-ID: 67bab8b8a4329a19a0add5085eacd6f4cc215e85 -commit 72bd68d37387aa5f81da928f6e82f1c88ed8f674 -Author: Darren Tucker -Date: Tue Mar 28 10:35:18 2023 +1100 +commit 019a5f483b0f588da6270ec401d0b4bb35032f3f +Author: deraadt@openbsd.org +Date: Tue Apr 2 09:29:31 2024 +0000 - Replace OPENSSL_NO_SHA with HEADER_SHA_H. + upstream: Use strtonum() instead of severely non-idomatic - Since this test doesn't use OpenSSL's SHA2 and may cause conflicts we - don't want to include it, but OPENSSL_NO_SHA was removed beginning in - OpenSSL's 1.1 series. - -commit 99668f2e6e0deb833e46cfab56db59ff0fc28c7e -Author: Darren Tucker -Date: Tue Mar 28 09:50:06 2023 +1100 - - Configure with --target instead of deprecated form. - -commit f751d9306c62cd1061f966e6a7483d9bab9c379b -Author: Darren Tucker -Date: Mon Mar 27 22:05:29 2023 +1100 - - Pass rpath when building 64bit Solaris. - -commit a64b935cd450ee8d04c26c9cd728629cf9ca5c91 -Author: Darren Tucker -Date: Mon Mar 27 19:21:19 2023 +1100 - - Explicitly disable OpenSSL on AIX test VM. + strtoul() In particular this will now reject trailing garbage, ie. + '12garbage'. ok djm + + OpenBSD-Commit-ID: c82d95e3ccbfedfc91a8041c2f8bf0cf987d1501 -commit 7ebc6f060fc2f70495a56e16d210baae6424cd96 -Author: dtucker@openbsd.org -Date: Mon Mar 27 03:56:50 2023 +0000 +commit 8231ca046fa39ea4eb99b79e0a6e09dec50ac952 +Author: deraadt@openbsd.org +Date: Mon Apr 1 15:50:17 2024 +0000 - upstream: Add RevokedHostKeys to percent expansion test. + upstream: also create a relink kit for ssh-agent, since it is a + + long-running setgid program carrying keys with some (not very powerful) + communication channels. solution for testing the binary from dtucker. + agreement from djm. Will add it into /etc/rc in a few days. - OpenBSD-Regress-ID: c077fd12a38005dd53d878c5b944154dec88d2ff + OpenBSD-Commit-ID: 2fe8d707ae35ba23c7916adcb818bb5b66837ba0 -commit f1a17de150f8d309d0c52f9abfaebf11c51a8537 -Author: dtucker@openbsd.org -Date: Mon Mar 27 03:56:11 2023 +0000 +commit bf7bf50bd6a14e49c9c243cb8f4de31e555a5a2e +Author: deraadt@openbsd.org +Date: Mon Apr 1 15:48:16 2024 +0000 - upstream: Add tilde and environment variable expansion to + upstream: new-style relink kit for sshd. The old scheme created - RevokedHostKeys. bz#3552, ok djm@ + a Makefile by concatenating two Makefiles and was incredibly fragile. In the + new way a narrow-purposed install.sh script is created and shipped with the + objects. A recently commited /etc/rc script understands these files. - OpenBSD-Commit-ID: ce5d8e0219b63cded594c17d4c2958c06918ec0d + OpenBSD-Commit-ID: ef9341d5a50f0d33e3a6fbe995e92964bc7ef2d3 -commit 009eb4cb48a9708ab9174684dcbcc0f942907abe -Author: djm@openbsd.org -Date: Mon Mar 27 03:31:05 2023 +0000 +commit 00e63688920905e326d8667cb47f17a156b6dc8f +Author: renmingshuai +Date: Fri Apr 12 10:20:49 2024 +0800 - upstream: fix test: getnameinfo returns a non-zero value on error, not - - (neccessarily) -1. From GHPR#384 + Shell syntax fix (leftover from a sync). - OpenBSD-Commit-ID: d35e2b71268f66f5543a7ea68751972b3ae22b25 + Signed-off-by: renmingshuai -commit 4f0a676486700f10a4788f7e9426e94e39c1c89e -Author: djm@openbsd.org -Date: Mon Mar 27 03:25:08 2023 +0000 +commit 2eded551ba96e66bc3afbbcc883812c2eac02bd7 +Author: Darren Tucker +Date: Thu Apr 25 13:20:19 2024 +1000 - upstream: scp: when copying local->remote, check that source file + Merge flags for OpenSSL 3.x versions. - exists before opening SFTP connection to the server. Based on GHPR#370 ok - dtucker, markus + OpenSSL has moved to 3.4 which we don't currently accept. Based on + the OpenSSL versioning policy[0] it looks like all of the 3.x versions + should work with OpenSSH, so remove the distinction in configure and + accept all of them. - OpenBSD-Commit-ID: b4dd68e15bfe22ce4fac9960a1066a2b721e54fb + [0] https://openssl.org/policies/general/versioning-policy.html -commit 154d8baf631327163571760c2c524bc93c37567c +commit 8673245918081c6d1dc7fb3733c8eb2c5a902c5e Author: Darren Tucker -Date: Mon Mar 27 12:22:30 2023 +1100 +Date: Thu Apr 25 13:19:03 2024 +1000 - Also look for gdb error message from OpenIndiana. + Remove 9.6 branch from status page. -commit fbd3811ddb2b6ce2e6dba91fde7352c8978e5412 +commit 70d43049747fa3c66cf876d52271859407cec2fa Author: Darren Tucker -Date: Mon Mar 27 11:08:00 2023 +1100 +Date: Thu Apr 25 13:16:58 2024 +1000 + + Update LibreSSL and OpenSSL versions tested. + + Update LibreSSL versions to current releases (3.8.4 & 3.9.1). + Add newly-released OpenSSL 3.3.0, and add tests against the 3.1 and + 3.3 branches. + +commit 88351eca17dcc55189991ba60e50819b6d4193c1 +Author: 90 +Date: Fri Apr 5 19:36:06 2024 +0100 + + Fix missing header for systemd notification + +commit 08f579231cd38a1c657aaa6ddeb8ab57a1fd4f5c +Author: Damien Miller +Date: Wed Apr 3 14:40:32 2024 +1100 - Explicitly disable security key test on aix51 VM. + notify systemd on listen and reload - We don't know how to build the shared objects required for the security - key tests so skip them. + Standalone implementation that does not depend on libsystemd. + With assistance from Luca Boccassi, and feedback/testing from Colin + Watson. bz2641 -commit 4922ac3be8a996780ef3dc220411da2e27c29d9c +commit 43e7c1c07cf6aae7f4394ca8ae91a3efc46514e2 Author: Darren Tucker -Date: Sun Mar 26 14:49:43 2023 +1100 +Date: Sun Mar 31 21:51:57 2024 +1100 - Split libcrypto and other config flags. + Port changes from selfhosted to upstream tests. - This should allow the automatic OpenSSL version selection in the tests - to work better. + Should get them working again. -commit 4a948b1469f185e871160a2d70e2a0fce2858f9e +commit 281ea25a44bff53eefb4af7bab7aa670b1f8b6b2 Author: Darren Tucker -Date: Sun Mar 26 14:39:45 2023 +1100 +Date: Sat Mar 30 18:20:16 2024 +1100 - Specify test target if we build without OpenSSL. + Check if OpenSSL implementation supports DSA. - When we decide we can't use the versions of OpenSSL available, also - restrict the tests we run to avoid the ones that need OpenSSL. + If --enable/disable-dsa-keys is not specified, set based on what OpenSSL + supports. If specified as enabled, but not supported by OpenSSL error + out. ok djm@ -commit b308c636f5b5d89eecb98be00b3d56306a005a09 -Author: Darren Tucker -Date: Sun Mar 26 14:22:53 2023 +1100 +commit 2d2c068de8d696fe3246f390b146197f51ea1e83 +Author: djm@openbsd.org +Date: Sat Mar 30 05:56:22 2024 +0000 - Find suitable OpenSSL version. + upstream: in OpenSSH private key format, correct type for subsequent + + private keys in blob. From Jakub Jelen via GHPR430 - Check the installed OpenSSL versions for a suitable one, and if there - isn't (and we don't have a specific version configured) then build - without OpenSSL. + OpenBSD-Commit-ID: d17dbf47554de2d752061592f95b5d772baab50b -commit 021ea5c2860f133f44790970968e0e73208b3a87 -Author: Damien Miller -Date: Fri Mar 24 15:02:52 2023 +1100 +commit c2c0bdd3e96b3ef66d77fccb85ff4962dc76caf0 +Author: Eero Häkkinen +Date: Sat Sep 16 00:55:08 2023 +0300 - Github testing support for BoringSSL + Expose SSH_AUTH_INFO_0 always to PAM auth modules. + + This changes SSH_AUTH_INFO_0 to be exposed to PAM auth modules also + when a password authentication method is in use and not only + when a keyboard-interactive authentication method is in use. -commit 9a97cd106466a2a9bda2bfaa4c48c4f1b2cc9c1b -Author: Damien Miller -Date: Fri Mar 24 15:34:29 2023 +1100 +commit 02c5ad23124ae801cf248d99ea5068fc4331ca01 +Author: Darren Tucker +Date: Wed Mar 27 17:42:58 2024 +1100 - BoringSSL doesn't support EC_POINT_point2bn() + Rearrange selfhosted VM scheduling. + + Instead of trying to infer the type of the self hosted tests in each of + the driver scripts (inconsistently...), set one of the following + variables to "true" in the workflow: + + VM: tests run in a virtual machine. + EPHEMERAL: tests run on an ephemeral virtual machine. + PERSISTENT: tests run on a persistent virtual machine + REMOTE: tests run on a physical remote host. + + EPHEMERAL VMs can have multiple instances of any given VM can exist + simultaneously and are run by a runner pool. The other types have a + dedicated runner instance and can only run a single test at a time. - so don't invoke it in unittest + Other settings: + SSHFS: We need to sshfs mount over the repo so the workflow can collect + build artifacts. This also implies the tests must be run over ssh. + DEBUG_ACTIONS: enable "set -x" in scripts for debugging. -commit cc5969c033a032d126ff78e5d95cf20abbede4c7 +commit cd8a72707c02615365d0851ac51063ab6bfe258f Author: Damien Miller -Date: Fri Mar 24 15:34:05 2023 +1100 +Date: Sat Mar 30 16:05:59 2024 +1100 - another ERR_load_CRYPTO_strings() vestige + add new token-based signing key for dtucker@ + + Verified in person and via signature with old key. + Will remove old key in a bit. -commit 4974293899a068133e976f81d6693670d2b576ca -Author: Damien Miller -Date: Fri Mar 24 15:24:05 2023 +1100 +commit 8d0e46c1ddb5b7f0992591b0dc5d8aaa77cc9dba +Author: Alkaid +Date: Tue Mar 12 03:59:12 2024 -0700 - don't use obsolete ERR_load_CRYPTO_strings() + Fix OpenSSL ED25519 support detection - OpenSSL (and elsewhere in OpenSSH) uses ERR_load_crypto_strings() + Wrong function signature in configure.ac prevents openssh from enabling + the recently new support for ED25519 priv keys in PEM PKCS8 format. -commit 3c527d55f906e6970d17c4cab6db90ae9e013235 -Author: Damien Miller -Date: Fri Mar 24 15:23:05 2023 +1100 +commit 697359be9c23ee43618243cdbcc9c7981e766752 +Author: djm@openbsd.org +Date: Sat Mar 30 04:27:44 2024 +0000 - Allow building with BoringSSL + upstream: allow WAYLAND_DISPLAY to enable SSH_ASKPASS + + From dkg via GHPR479; ok dtucker@ + + OpenBSD-Commit-ID: 1ac1f9c45da44eabbae89375393c662349239257 -commit b7e27cfd7f163fc16b4c5d041cc28ee488a5eeec -Author: Damien Miller -Date: Fri Mar 24 15:21:18 2023 +1100 +commit 7844705b0364574cc70b941be72036c2c2966363 +Author: dtucker@openbsd.org +Date: Fri Mar 29 10:40:07 2024 +0000 - put back SSLeay_version compat in configure test + upstream: Use egrep instead of grep -E. - Needed to detect old versions and give good "your version is bad" - messages at configure time; spotted by dtucker@ + Some plaforms don't have the latter so this makes things easier + in -portable. + + OpenBSD-Regress-ID: ff82260eb0db1f11130200b25d820cf73753bbe3 -commit 7280401bdd77ca54be6867a154cc01e0d72612e0 -Author: Damien Miller -Date: Fri Mar 24 13:56:25 2023 +1100 +commit 22b2b6c555334bffdf357a2e4aa74308b03b83c3 +Author: dtucker@openbsd.org +Date: Tue Mar 26 08:09:16 2024 +0000 - remove support for old libcrypto + upstream: test -h is the POSIXly way of testing for a symlink. Reduces - OpenSSH now requires LibreSSL 3.1.0 or greater or - OpenSSL 1.1.1 or greater + diff vs Portable. - with/ok dtucker@ + OpenBSD-Regress-ID: 6f31cd6e231e3b8c5c2ca0307573ccb7484bff7d -commit abda22fb48302f2142233f71d27c74040288c518 +commit edcff77f82c2bb2b5653b36f1e47274c5ef3e8be Author: Darren Tucker -Date: Sun Mar 19 15:36:13 2023 +1100 +Date: Tue Mar 26 18:58:58 2024 +1100 - Test latest OpenSSL 1.1, 3.0 and LibreSSL 3.7. + Fix name of OpenBSD upstream CI jobs. -commit 610ac1cb077cd5a1ebfc21612154bfa13d2ec825 +commit 861b084429940e024f1b6e9c2779eac95d7a45db Author: Darren Tucker -Date: Thu Mar 16 21:38:04 2023 +1100 - - Show 9.3 branch instead of 9.2. - -commit cb30fbdbee869f1ce11f06aa97e1cb8717a0b645 -Author: Damien Miller -Date: Thu Mar 16 08:28:19 2023 +1100 - - depend - -commit 1dba63eb10c40b6fda9f5012ed6ae87e2d3d028e -Author: Damien Miller -Date: Thu Mar 16 08:27:54 2023 +1100 +Date: Tue Mar 26 18:55:33 2024 +1100 - crank version + Resync with upstream: ${} around DATAFILE. -commit ba7532d0dac9aaf0ad7270664c43837fc9f64a5f +commit 63f248c7693e7f0a3b9a13d2980ac9a7e37f2aea Author: djm@openbsd.org -Date: Wed Mar 15 21:19:57 2023 +0000 +Date: Mon Mar 25 19:28:09 2024 +0000 - upstream: openssh-9.3 + upstream: optional debugging - OpenBSD-Commit-ID: 8011495f2449c1029bb316bd015eab2e00509848 + OpenBSD-Regress-ID: b4852bf97ac8fb2e3530f2d5f999edd66058d7bc -commit 6fd4daafb949b66bf555f3100f715a9ec64c3390 +commit 16e2ebe06a62f09d4877b769876d92d6008a896f Author: dtucker@openbsd.org -Date: Tue Mar 14 07:28:47 2023 +0000 +Date: Mon Mar 25 06:05:42 2024 +0000 - upstream: Free KRL ptr in addition to its contents. - - From Coverity CID 291841, ok djm@ + upstream: Verify string returned from local shell command. - OpenBSD-Commit-ID: f146ba08b1b43af4e0d7ad8c4dae3748b4fa31b6 + OpenBSD-Regress-ID: 5039bde24d33d809aebfa8d3ad7fe9053224e6f8 -commit 1d270bd303afaf6d94e9098cbbf18e5e539e2088 +commit b326f7a1f39ff31324cc3fe2735178fb474c04a4 Author: dtucker@openbsd.org -Date: Tue Mar 14 07:26:25 2023 +0000 +Date: Mon Mar 25 03:30:31 2024 +0000 - upstream: Check pointer for NULL before deref. + upstream: Improve shell portability: grep -q is not portable so - None of the existing callers seem to do that, but it's worth checking. - From Coverity CID 291834, ok djm@ + redirect stdout, and use printf instead of relying on echo to do \n + substitution. Reduces diff vs Portable. + + Also resync somewhat with upstream. - OpenBSD-Commit-ID: a0a97113f192a7cb1a2c97b932f677f573cda7a4 + OpenBSD-Regress-ID: 9ae876a8ec4c4725f1e9820a0667360ee2398337 -commit d95af508e78c0cd3dce56b83853baaa59ae295cf +commit dbf2e319f0c582613fa45a735ea3c242ce56946b Author: dtucker@openbsd.org -Date: Sun Mar 12 10:40:39 2023 +0000 +Date: Mon Mar 25 02:07:08 2024 +0000 - upstream: Limit number of entries in SSH2_MSG_EXT_INFO + upstream: Save error code from SSH for use inside case statement, - request. This is already constrained by the maximum SSH packet size but this - makes it explicit. Prompted by Coverity CID 291868, ok djm@ markus@ + from portable. In some shells, "case" will reset the value of $?, so save it + first. - OpenBSD-Commit-ID: aea023819aa44a2dcb9dd0fbec10561896fc3a09 + OpenBSD-Regress-ID: da32e5be19299cb4f0f7de7f29c11257a62d6949 -commit 8f287ba60d342b3e2f750e7332d2131e3ec7ecd0 +commit d2c8c4fa7def4fb057ed05b3db57b62c810a26f6 Author: dtucker@openbsd.org -Date: Sun Mar 12 09:41:18 2023 +0000 +Date: Mon Mar 25 01:40:47 2024 +0000 - upstream: calloc can return NULL but xcalloc can't. + upstream: Increase timeout. Resyncs with portable where some of - From Coverity CID 291881, ok djm@ + the test VMs are slow enough for this to matter. - OpenBSD-Commit-ID: 50204b755f66b2ec7ac3cfe379d07d85ca161d2b + OpenBSD-Regress-ID: 6a83a693602eb0312f06a4ad2cd6f40d99d24b26 -commit 83a56a49fd50f4acf900f934279482e4ef329715 +commit 83621b63514a84791623db3efb59d38bc4bf9563 Author: dtucker@openbsd.org -Date: Fri Mar 10 07:17:08 2023 +0000 +Date: Mon Mar 25 01:28:29 2024 +0000 - upstream: Explicitly ignore return from fcntl + upstream: In PuTTY interop test, don't assume the PuTTY major - (... FD_CLOEXEC) here too. Coverity CID 291853. + version is 0. Patch from cjwatson at debian.org via bz#3671. - OpenBSD-Commit-ID: 99d8b3da9d0be1d07ca8dd8e98800a890349e9b5 + OpenBSD-Regress-ID: 835ed03c1b04ad46be82e674495521f11b840191 -commit 0fda9d704d3bbf54a5e64ce02a6fecb11fe7f047 -Author: Damien Miller -Date: Fri Mar 10 15:59:46 2023 +1100 +commit 8a421b927700f3834b4d985778e252b8e3299f83 +Author: Darren Tucker +Date: Tue Mar 26 18:38:14 2024 +1100 - bounds checking for getrrsetbyname() replacement; - - Spotted by Coverity in CID 405033; ok millert@ + Really mkdir /usr/local/etc in CI tests. -commit 89b8df518f21677045599df0ad3e5dd0f39909b5 -Author: dtucker@openbsd.org -Date: Fri Mar 10 04:06:21 2023 +0000 +commit 2946ed522c47ce045314533d426b4e379f745e59 +Author: Darren Tucker +Date: Tue Mar 26 17:19:09 2024 +1100 - upstream: Plug mem leak on error path. Coverity CID 405026, ok djm@. - - OpenBSD-Commit-ID: 8212ca05d01966fb5e72205c592b2257708a2aac + Better short name for OpenBSD upstream CI jobs too. -commit bf4dae0ad192c3e2f03f7223834b00d88ace3d3e +commit 18dbe8eff647aacb82d7e86b4ce63d5beee11f25 Author: Darren Tucker -Date: Fri Mar 10 14:46:57 2023 +1100 +Date: Tue Mar 26 17:13:52 2024 +1100 - Add prototypes for mkstemp replacements. - - Should prevent warnings due to our wrapper function. + Ensure /usr/local/etc exists before using in tests. -commit 4e04d68d6a33cdc73b831fd4b5e6124175555d3d -Author: dtucker@openbsd.org -Date: Fri Mar 10 03:01:51 2023 +0000 +commit 5fc1085128e3348bb1b5ee4d955cc767b019b3ad +Author: Darren Tucker +Date: Tue Mar 26 16:50:46 2024 +1100 - upstream: Expliticly ignore return code from fcntl(.. FD_CLOEXEC) since - - there's not much we can do anyway. From Coverity CID 291857, ok djm@ - - OpenBSD-Commit-ID: 051429dd07af8db3fec10d82cdc78d90bb051729 + Be more specific about when to rerun workflows. -commit d6d38fd77cbe091c59e1bb720c3a494df4990640 -Author: djm@openbsd.org -Date: Fri Mar 10 02:32:04 2023 +0000 +commit 5516923e8ae3da0823fea0d7d28aa813627142c0 +Author: Darren Tucker +Date: Tue Mar 26 16:35:27 2024 +1100 - upstream: Like sshd_config, some ssh_config options are not - - first-match-wins. sshd_config.5 was fixed in r1.348, this is the same for - this file - - OpenBSD-Commit-ID: 7be55b9351cde449b136afcc52d07aa4113b215e + Add short names for test jobs on github CI. -commit 7187d3f86bf8f2066cc9941f217d23b0cacae25e -Author: dtucker@openbsd.org -Date: Fri Mar 10 02:24:56 2023 +0000 +commit dc37d2d2470b4a9cedcee9ac926b7362214e3305 +Author: Darren Tucker +Date: Tue Mar 26 16:26:14 2024 +1100 - upstream: Remove no-op (int) > INT_MAX checks - - since they can never be true. From Coverity CID 405031, ok djm@ - - OpenBSD-Commit-ID: 9df3783b181e056595e2bb9edf7ed41d61cf8e84 + If we're using xpg4's id, remember to pass args. -commit 77adde4305542ebe3005dd456122624fe2347b01 -Author: Darren Tucker -Date: Fri Mar 10 13:27:29 2023 +1100 +commit fe169487937780392b23d3ff3c00e5898c10f784 +Author: dtucker@openbsd.org +Date: Tue Mar 26 01:23:11 2024 +0000 - Wrap mkstemp calls with umask set/restore. + upstream: Import regenerated moduli. - glibc versions 2.06 and earlier did not set a umask on files created by - mkstemp created the world-writable. Wrap mkstemp to set and restore - the umask. From Coverity (CIDs 291826 291886 291891), ok djm@ + OpenBSD-Commit-ID: ad3d1486d105b008c93e952d158e5af4d9d4c531 -commit 633d3dc2a1e9e2a013d019a0576a0771c8423713 -Author: jcs@openbsd.org -Date: Thu Mar 9 21:06:24 2023 +0000 +commit 151146f03b490d19145cd421763aa7d42f5c50e2 +Author: job@openbsd.org +Date: Thu Mar 14 06:23:14 2024 +0000 - upstream: modify parentheses in conditionals to make it clearer what is - - being assigned and what is being checked + upstream: Clarify how literal IPv6 addresses can be used in -J mode - ok djm dtucker + OK djm@ - OpenBSD-Commit-ID: 19c10baa46ae559474409f75a5cb3d0eade7a9b8 + OpenBSD-Commit-ID: 524ddae97746b3563ad4a887dfd0a6e6ba114c50 -commit 733030840c4772f858de95d5940ec0c37663e8b0 -Author: dtucker@openbsd.org -Date: Thu Mar 9 07:11:05 2023 +0000 +commit 0d5bdc87a675271862b67eb6a9fb13a202fb4894 +Author: Darren Tucker +Date: Mon Mar 25 16:14:21 2024 +1100 - upstream: Re-split the merge of the reorder-hostkeys test. - - In the kex_proposal_populate_entries change I merged the the check for - reordering hostkeys with the actual reordering, but kex_assemble_names - mutates options.hostkeyalgorithms which renders the check ineffective. - Put the check back where it was. Spotted and tested by jsg@, ok djm@ - - OpenBSD-Commit-ID: a7469f25a738db5567395d1881e32479a7ffc9de + Add Mac OS X 14 test targets. -commit 54ac4ab2b53ce9fcb66b8250dee91c070e4167ed -Author: djm@openbsd.org -Date: Thu Mar 9 06:58:26 2023 +0000 +commit 2d7964a03e1f50a48040ec6912c0a956df909d21 +Author: Darren Tucker +Date: Mon Mar 25 14:05:40 2024 +1100 - upstream: include destination constraints for smartcard keys too. - - Spotted by Luci Stanescu; ok deraadt@ markus@ + Move xpg4 'id' handling into test-exec.sh. - OpenBSD-Commit-ID: add879fac6903a1cb1d1e42c4309e5359c3d870f + Handle replacement of 'id' the same way as we do other Portable specific + replacements in test-exec.sh. This brings percent.sh back into sync + with upstream. -commit bfd1ad01d974a316b60622759ad17537fa2d92b4 +commit 75d1d49ed10d978171cdafad28bdbffdbd48f41e Author: Darren Tucker -Date: Thu Mar 9 18:24:54 2023 +1100 +Date: Mon Mar 25 10:38:03 2024 +1100 - Limit the number of PAM environment variables. - - xcalloc has its own limits, but these are specific to PAM. From - Coverity CID 405198, ok djm@ + Update branches shown on ci-status to 9.7 and 9.6. -commit a231414970e01a35f45a295d5f93698fa1249b28 +commit f9193f03db0029fc9c31fbdb5c66a2737446bd8f Author: Darren Tucker -Date: Thu Mar 9 18:19:44 2023 +1100 +Date: Mon Mar 25 09:28:02 2024 +1100 - Limit the number of PAM environment variables. + Improve detection of -fzero-call-used-regs=used. + + Should better detect problems with gcc 13 on m68k. bz#3673 from Colin + Watson via bz#3673 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110934 - From Coverity CID 405194, tweaks and ok djm@ + Signed-off-by: Darren Tucker -commit 36c6c3eff5e4a669ff414b9daf85f919666e8e03 -Author: dtucker@openbsd.org -Date: Wed Mar 8 06:21:32 2023 +0000 +commit 86bdd3853f4d32c85e295e6216a2fe0953ad93f0 +Author: Damien Miller +Date: Mon Mar 11 16:20:49 2024 +1100 - upstream: Plug mem leak. Coverity CID 405196, ok djm@ - - OpenBSD-Commit-ID: 175f09349387c292f626da68f65f334faaa085f2 + version number in README -commit dfb9b736e1ccf9e6b03eea21cd961f4fd0634c98 -Author: tb@openbsd.org -Date: Wed Mar 8 05:33:53 2023 +0000 +commit 282721418e6465bc39ccfd39bb0133e670ee4423 +Author: Damien Miller +Date: Mon Mar 11 16:20:08 2024 +1100 - upstream: ssh-pkcs11: synchronize error messages with errors - - A handful of error messages contained incorrect function names or - otherwise inaccurate descriptions. Fix them to match reality. - - input/ok djm - - OpenBSD-Commit-ID: 165a15db52f75b31e1804b043480c36af09f3411 + crank RPM spec versions -commit 51875897b81b5c21b80c256a29597916edbde454 -Author: guenther@openbsd.org -Date: Wed Mar 8 04:43:12 2023 +0000 +commit 3876a3bbd2ca84d23ba20f8b69ba83270c04ce3a +Author: djm@openbsd.org +Date: Mon Mar 11 04:59:47 2024 +0000 - upstream: Delete obsolete /* ARGSUSED */ lint comments. - - ok miod@ millert@ + upstream: openssh-9.7 - OpenBSD-Commit-ID: 7be168a570264d59e96a7d2d22e927d45fee0e4c + OpenBSD-Commit-ID: 618ececf58b8cdae016b149787af06240f7b0cbc -commit a76085bda883c2104afb33ab0334eca190927362 +commit 8fc109cc614954a8eb2738c48c0db36a62af9a06 Author: Darren Tucker -Date: Wed Mar 8 17:25:37 2023 +1100 +Date: Mon Mar 11 12:59:26 2024 +1100 - Extra brackets to prevent warning. + Test against current OpenSSL and LibreSSL releases. + + Add LibreSSL 3.9.0, bump older branches to their respective current + releases. -commit 147ae57d4dfa0508109f93b78a7d8b92819e1f83 -Author: djm@openbsd.org -Date: Wed Mar 8 00:05:58 2023 +0000 +commit 26b09b45fec7b88ba09042c09be4157e58e231e2 +Author: Damien Miller +Date: Sun Mar 10 16:24:57 2024 +1100 - upstream: use RSA/SHA256 when testing usability of private key in - - agent; with/ok dtucker + quote regexes used to test for algorithm support - OpenBSD-Commit-ID: fe1382e2fdf23fcae631308e72342bad56066a56 + Fixes test failures on Solaris 8 reported by Tom G. Christensen -commit 27fd251bc906a763e70ce0f27c8abdf8bbd1e416 +commit a6a740a4948d10a622b505135bb485c10f21db5e Author: djm@openbsd.org -Date: Wed Mar 8 00:05:37 2023 +0000 +Date: Sat Mar 9 05:12:13 2024 +0000 - upstream: use RSA/SHA256 when testing usability of private key; + upstream: avoid logging in signal handler by converting mainloop to - based on fix in bz3546 by Dmitry Belyavskiy; with/ok dtucker + ppoll() bz3670, reported by Ben Hamilton; ok dtucker@ - OpenBSD-Commit-ID: 0ef414cc363a832f9fab92a5da0234448bce2eba + OpenBSD-Commit-ID: e58f18042b86425405ca09e6e9d7dfa1df9f5f7f -commit eee9f3fc3d52ae7d2106929bb06b7f291fb0b81a +commit cd82f7526e0481720567ae41db7849ab1c27e27b Author: djm@openbsd.org -Date: Tue Mar 7 21:47:42 2023 +0000 +Date: Fri Mar 8 22:16:32 2024 +0000 - upstream: refactor to be more readable top to bottom. Prompted by + upstream: skip more whitespace, fixes find-principals on - Coverity CID 405048 which was a false-positive fd leak; ok dtucker@ + allowed_signers files with blank lines; reported by Wiktor Kwapisiewicz - OpenBSD-Commit-ID: fc55ec2af622a017defb9b768bf26faefc792c00 - -commit 42a06b29a4c99272bf690f9b3be520b08b448dc5 -Author: Darren Tucker -Date: Tue Mar 7 18:34:41 2023 +1100 - - Add header changes missed in previous. + OpenBSD-Commit-ID: b3a22a2afd753d70766f34bc7f309c03706b5298 -commit 4710077096edff2e6926dd5b15bf586491d317db +commit 2f9d2af5cb19905d87f37d1e11c9f035ac5daf3b Author: dtucker@openbsd.org -Date: Tue Mar 7 06:09:14 2023 +0000 +Date: Fri Mar 8 11:34:10 2024 +0000 - upstream: Fix mem leak in environment setup. + upstream: Invoke ProxyCommand that uses stderr redirection via - From jjelen at redhat.com via bz#2687, ok djm@ + $TEST_SHELL. Fixes test when run by a user whose login shell is tcsh. + Found by vinschen at redhat.com. - OpenBSD-Commit-ID: 9f9e4ba3cac003e6f81da3bcebd1b9ec43e7f353 + OpenBSD-Regress-ID: f68d79e7f00caa8d216ebe00ee5f0adbb944062a -commit 03acc50d0ccb78fc91d1570de1cd0fdfea646028 -Author: dtucker@openbsd.org -Date: Mon Mar 6 12:15:47 2023 +0000 +commit 9b3f0beb4007a7e01dfedabb429097fb593deae6 +Author: Darren Tucker +Date: Thu Mar 7 17:18:14 2024 +1100 - upstream: Unit test for kex_proposal_populate_entries. + Prefer openssl binary from --with-ssl-dir directory. - OpenBSD-Regress-ID: bdb211d80d572a08bf14b49fe2a58b9ff265c006 + Use openssl in the directory specified by --with-ssl-dir as long + as it's functional. Reported by The Doctor. -commit 3f9231c2e1f374ebb08016ba00ea97b47c0ed20b +commit c47e1c9c7911f38b2fc2fb01b1f6ae3a3121a838 Author: djm@openbsd.org -Date: Tue Mar 7 05:37:26 2023 +0000 +Date: Wed Mar 6 02:59:59 2024 +0000 - upstream: fix memory leak in process_read() path; Spotted by James + upstream: fix memory leak in mux proxy mode when requesting forwarding. - Robinson in GHPR363; ok markus@ + found by RASU JSC, reported by Maks Mishin in GHPR#467 - OpenBSD-Commit-ID: cdc2d98e6478b7e7f3a36976845adae3820429d8 + OpenBSD-Commit-ID: 97d96a166b1ad4b8d229864a553e3e56d3116860 -commit c5e6e890839ec520ab9301a92cba56303749dea2 +commit 242742827fea4508e68097c128e802edc79addb5 Author: djm@openbsd.org -Date: Tue Mar 7 01:30:52 2023 +0000 +Date: Wed Mar 6 00:31:04 2024 +0000 - upstream: correct size for array argument when changing - - UMAC_OUTPUT_LEN Coverity CID 291845; ok dtucker@ + upstream: wrap a few PKCS#11-specific bits in ENABLE_PKCS11 - OpenBSD-Commit-ID: 2eb017d10705bb623d4418691f961c930eafaec0 + OpenBSD-Commit-ID: 463e4a69eef3426a43a2b922c4e7b2011885d923 -commit 9641753e0fd146204d57b2a4165f552a81afade4 -Author: dtucker@openbsd.org -Date: Mon Mar 6 12:14:48 2023 +0000 +commit d52b6509210e2043f33e5a1de58dd4a0d5d48c2a +Author: Damien Miller +Date: Wed Mar 6 11:31:36 2024 +1100 - upstream: Refactor creation of KEX proposal. + disable RSA tests when algorithm is not supported - This adds kex_proposal_populate_entries (and corresponding free) which - populates the KEX proposal array with dynamically allocated strings. - This replaces the previous mix of static and dynamic that has been the - source of previous leaks and bugs. Remove unused compat functions. - With & ok djm@. + Unbreaks "make test" when compiled --without-openssl. - OpenBSD-Commit-ID: f2f99da4aae2233cb18bf9c749320c5e040a9c7b + Similar treatment to how we do DSA and ECDSA. -commit aa59d6a489fb20973fa461d0fdb1110db412947b -Author: dtucker@openbsd.org -Date: Sun Mar 5 09:24:35 2023 +0000 +commit 668d270a6c77e8b5a1da26ecad2e6de9f62c8fe4 +Author: Damien Miller +Date: Wed Mar 6 10:33:20 2024 +1100 - upstream: Fix mem and FILE leaks in moduli screening. - - If multiple -Ocheckpoint= options are passed, the earlier ones would - be overwritten and leaked. If we use an input file that wasn't stdin, - close that. From Coverity CIDs 291884 and 291894. + add a --without-retpoline configure option - OpenBSD-Commit-ID: a4d9d15f572926f841788912e2b282485ad09e8b + discussed with deraadt and dtucker a while ago -commit 23b8cb41767af99a1aac24589d1882d9c8c2c205 -Author: dtucker@openbsd.org -Date: Sun Mar 5 08:18:58 2023 +0000 +commit 3deb501f86fc47e175ef6a3eaba9b9846a80d444 +Author: djm@openbsd.org +Date: Mon Mar 4 04:13:18 2024 +0000 - upstream: Plug mem leak in moduli checkpoint option parsing. + upstream: fix leak of CanonicalizePermittedCNAMEs on error path; - From Coverity CID 291894. + spotted by Coverity (CID 438039) - OpenBSD-Commit-ID: 9b1aba2d049741ae21c8dc4560a7e29ab17310f4 + OpenBSD-Commit-ID: 208839699939721f452a4418afc028a9f9d3d8af -commit fc7f8f2188d4a4fc8ba77eddbe863c7665666db5 -Author: dtucker@openbsd.org -Date: Sun Mar 5 05:34:09 2023 +0000 +commit 65a44a8a4f7d902a64d4e60eda84384b2e2a24a2 +Author: djm@openbsd.org +Date: Mon Mar 4 02:16:11 2024 +0000 - upstream: Remove unused compat.h includes. + upstream: Separate parsing of string array options from applying them - We've previously removed a lot of the really old compatibility code, - and with it went the need to include compat.h in most of the files that - have it. + to the active configuration. This fixes the config parser from erroneously + rejecting cases like: - OpenBSD-Commit-ID: 5af8baa194be00a3092d17598e88a5b29f7ea2b4 - -commit 6c165c36246d8004c20e1df5cec4961a5ac422d6 -Author: dtucker@openbsd.org -Date: Sat Mar 4 03:22:59 2023 +0000 - - upstream: Use time_t for x11 timeout. + AuthenticationMethods password + Match User ivy + AuthenticationMethods any - Use time_t instead of u_int for remaining x11 timeout checks for 64bit - time_t safety. From Coverity CIDs 405197 and 405028, ok djm@ + bz3657 ok markus@ - OpenBSD-Commit-ID: 356685bfa1fc3d81bd95722d3fc47101cc1a4972 + OpenBSD-Commit-ID: 7f196cba634c2a3dba115f3fac3c4635a2199491 -commit 4a3918f51bd2d968387e7aa87e33b32c78077fb4 -Author: dtucker@openbsd.org -Date: Fri Mar 3 10:23:42 2023 +0000 +commit 6886e1b1f55c90942e4e6deed930f8ac32e0f938 +Author: Darren Tucker +Date: Thu Feb 22 17:59:35 2024 +1100 - upstream: Ensure ms_remain is always initialized - - similar to what we do in ssh_packet_write_wait. bz#2687, from jjelen - at redhat.com. - - OpenBSD-Commit-ID: a50e0541cf823f8d1c72f71ccde925d3dbe6dfac + Add nbsd10 test target. -commit e44846a4487d2885ac7f2610be09b1e2bf52249b -Author: dtucker@openbsd.org -Date: Fri Mar 3 09:48:51 2023 +0000 +commit d86bf8a3f6ea4fa7887406c2aa9959db71fa41be +Author: Damien Miller +Date: Thu Feb 22 12:06:10 2024 +1100 - upstream: Check for non-NULL before string - - comparison. From jjelen at redhat.com via bz#2687. - - OpenBSD-Commit-ID: 0d9b2e0cac88a311b5766b1aef737082583c285f + more descriptive configure test name -commit 1842d523fae63b862ce8e60725c9b606cddb86a6 +commit 9ee335aacc9f5bdc4cc2c19fafb45e27be7d234e Author: djm@openbsd.org -Date: Fri Mar 3 05:00:34 2023 +0000 +Date: Wed Feb 21 06:17:29 2024 +0000 - upstream: guard against getsockname(-1, ...) from Coverity CID + upstream: explain arguments of internal-sftp GHPR#454 from Niklas - 291832 + Hambüchen + MIME-Version: 1.0 + Content-Type: text/plain; charset=UTF-8 + Content-Transfer-Encoding: 8bit - OpenBSD-Commit-ID: e58d5227327917d189229b7f0b37d2780f360d5f + OpenBSD-Commit-ID: 0335d641ae6b5b6201b9ffd5dd06345ebbd0a3f3 -commit 78571a5fe9847d40d7f220c92b707574ae9ec4ce +commit d1164cb1001dd208fee88aaa9b43d5e6fd917274 Author: djm@openbsd.org -Date: Fri Mar 3 04:36:20 2023 +0000 +Date: Wed Feb 21 06:06:43 2024 +0000 - upstream: some options are not first-match-wins. Mention that there + upstream: clarify permissions requirements for ChrootDirectory Part - are exceptions at the start of the manpage and label some of them in the - option description. + of GHPR#454 from Niklas Hambüchen + MIME-Version: 1.0 + Content-Type: text/plain; charset=UTF-8 + Content-Transfer-Encoding: 8bit - OpenBSD-Commit-ID: 3b74728446fa6fc8742769eeb8c3674e233e84c4 + OpenBSD-Commit-ID: d37bc8786317a11649c62ff5e2936441186ef7a0 -commit d1c1b3272e8895a96c4f5889bd6e07a8525bd9f1 +commit d410e17d186552d0717f18217d0d049486754365 Author: djm@openbsd.org -Date: Fri Mar 3 04:34:49 2023 +0000 +Date: Wed Feb 21 06:05:06 2024 +0000 - upstream: actually print "channeltimeout none" in config dump mode; - - spotted via Coverity CID 405022 + upstream: .Cm for a keyword. Part of GHPR#454 from Niklas Hambüchen - OpenBSD-Commit-ID: b074b52bf138b75f08264e8da15880b29c7a630f - -commit 8bf61e95610b48192d4e1720cc15d9004617301d -Author: Darren Tucker -Date: Fri Mar 3 14:50:03 2023 +1100 - - Add Coverity badges. + OpenBSD-Commit-ID: d59c52559f926fa82859035d79749fbb4a3ce18a -commit 93291bd723959adf462b1df958106cf07a7734dd -Author: dtucker@openbsd.org -Date: Fri Mar 3 03:12:24 2023 +0000 +commit ab73f9678ebf06b32d6361b88b50b42775e0565b +Author: djm@openbsd.org +Date: Wed Feb 21 06:01:13 2024 +0000 - upstream: Check return values of dup2. Spotted by Coverity, ok djm@ + upstream: fix typo in match directive predicate (s/tagged/tag) GHPR#462 + + from Tobias Manske - OpenBSD-Commit-ID: 19fb1b53072826d00c67df677731d2f6c1dd602b + OpenBSD-Commit-ID: 05b23b772677d48aa82eefd7ebebd369ae758908 -commit e37261dff33af23f37202cfce0848d36f5c1055c -Author: dtucker@openbsd.org -Date: Fri Mar 3 02:37:58 2023 +0000 +commit 9844aa2521ccfb1a2d73745680327b79e0574445 +Author: djm@openbsd.org +Date: Wed Feb 21 05:57:34 2024 +0000 - upstream: Use time_t for x11_refuse_time timeout. We need + upstream: fix proxy multiplexing mode, broken when keystroke timing - SSH_TIME_T_MAX for this, so move from misc.c to misc.h so it's available. - Fixes a Coverity warning for 64bit time_t safety, ok djm@ + obfuscation was added. GHPR#463 from montag451 - OpenBSD-Commit-ID: c69c4c3152cdaab953706db4ccf4d5fd682f7d8d + OpenBSD-Commit-ID: 4e412d59b3f557d431f1d81c715a3bc0491cc677 -commit 32755a98c29114b13f4c9d47454bbb265b932ad7 -Author: dtucker@openbsd.org -Date: Fri Mar 3 02:34:29 2023 +0000 +commit ee6d932acb532f80b11bb7cf161668c70ec8a117 +Author: djm@openbsd.org +Date: Tue Feb 20 04:10:03 2024 +0000 - upstream: Check return value from fctnl and warn on failure. + upstream: don't append a gratuitous space to the end of subsystem - Spotted by Coverity, ok djm@ + arguments; bz3667 - OpenBSD-Commit-ID: 2097c7db3cf657f1e3a6c5077041bacc63143cab + OpenBSD-Commit-ID: e11023aeb3f30b77a674e37b8292c862926d5dc6 -commit 5fc60e8246c36b8255f72a937ebe9787b39648c6 +commit e27f032aa8fcbae9b2e7c451baaf4b8ac6fa3d45 Author: dtucker@openbsd.org -Date: Thu Mar 2 11:10:27 2023 +0000 +Date: Mon Feb 19 09:25:52 2024 +0000 - upstream: Remove SUDO in proxy command wrapper. Anything that needs - - sudo is already run by it, and it breaks if root isn't in sudoers. + upstream: Always define puttysetup function. - OpenBSD-Regress-ID: 6cf22fda32a89c16915f31a6ed9bbdbef2a3bac9 + OpenBSD-Regress-ID: b4c0ccfa4006a1bc5dfd99ccf21c854d3ce2aee0 -commit 0d514659b23a257247491179cfbb53a6dd64e164 +commit 84046f9991abef5f46b040b10cf3d494f933a17b Author: dtucker@openbsd.org -Date: Thu Mar 2 08:24:41 2023 +0000 +Date: Fri Feb 9 08:56:59 2024 +0000 - upstream: Fix breakage on dhgex test. + upstream: Exapnd PuTTY test coverage. - This was due to the sshd logs being written to the wrong log file. - While there, make save_debug_logs less verbose, write the name of the - tarball to regress.log and use $SUDO to remove the old symlinks (which - shouldn't be needed, but won't hurt). Initial problem spotted by anton@. + Expand the set of ciphers, MACs and KEX methods in the PuTTY interop + tests. - OpenBSD-Regress-ID: 9c44fb9cd418e6ff31165e7a6c1f9f11a6d19f5b + OpenBSD-Regress-ID: dd28d97d48efe7329a396d0d505ee2907bf7fc57 -commit 860201201d4ae655702807966901682cff30a171 +commit bbf541ee2afe07b08a8b56fa0dc6f38fcfceef2a Author: dtucker@openbsd.org -Date: Thu Mar 2 08:14:52 2023 +0000 +Date: Fri Feb 9 08:47:42 2024 +0000 - upstream: Quote grep and log message better. + upstream: Factor out PuTTY setup. - OpenBSD-Regress-ID: 3823d9063127169736aa274b1784cb28e15b64d4 - -commit 03a03c6002525f5ad9c8fc874a5d5826a35d9858 -Author: dtucker@openbsd.org -Date: Thu Mar 2 06:41:56 2023 +0000 - - upstream: Always call fclose on checkpoints. + Factor out PuTTY and call only when needed. - In the case of an fprintf failure we would not call fclose which would - leak the FILE pointer. While we're there, try to clean up the temp file - on failure. Spotted by Coverity, ok djm@ + This allows us to avoid PuTTY key setup when it's not needed, which + speeds up the overall test run by a couple of percent. - OpenBSD-Commit-ID: 73c7ccc5d4fcc235f54c6b20767a2815408525ef + OpenBSD-Regress-ID: c25eaccc3c91bc874400f7c85ce40e9032358c1c -commit 13fe8f9785e6d90400ce548939a0b0ddc11fcb3c -Author: dtucker@openbsd.org -Date: Wed Mar 1 21:54:50 2023 +0000 +commit d31c21c57fb4245271680a1e5043cf6470a96766 +Author: naddy@openbsd.org +Date: Sat Feb 10 11:28:52 2024 +0000 - upstream: Remove old log symlinks - - before creating new ones. In -portable some platforms don't like - overwriting existing symlinks. + upstream: clean sshd random relinking kit; ok miod@ - OpenBSD-Regress-ID: 7e7ddc0beb73e945e1c4c58d51c8a125b518120f - -commit 131fcbcaffd1e3bcf5ab766ec497b5d768955310 -Author: Darren Tucker -Date: Wed Mar 1 23:23:02 2023 +1100 - - Adjust test jobs for new log directory. + OpenBSD-Commit-ID: 509bb19bb9762a4b3b589af98bac2e730541b6d4 -commit a6f4ac8a2baf77e5361cfa017d0dc250d1409bec -Author: dtucker@openbsd.org -Date: Wed Mar 1 09:29:32 2023 +0000 +commit 4dbc5a363ff53a2fcecf6bc3bcc038badc12f118 +Author: djm@openbsd.org +Date: Fri Feb 2 00:13:34 2024 +0000 - upstream: Rework logging for the regression tests. - - Previously we would log to ssh.log and sshd.log, but that is insufficient - for tests that have more than one concurent ssh/sshd. - - Instead, we'll log to separate datestamped files in a $OBJ/log/ and - leave a symlink at the previous location pointing at the most recent - instance with an entry in regress.log showing which files were created - at each point. This should be sufficient to reconstruct what happened - even for tests that use multiple instances of each program. If the test - fails, tar up all of the logs for later analysis. - - This will let us also capture the output from some of the other tools - which was previously sent to /dev/null although most of those will be - in future commits. + upstream: whitespace - OpenBSD-Regress-ID: f802aa9e7fa51d1a01225c05fb0412d015c33e24 + OpenBSD-Commit-ID: b24680bc755b621ea801ff8edf6f0f02b68edae1 -commit 8ead62ed5e86c7df597d8604f332f49cd1527b85 -Author: dtucker@openbsd.org -Date: Tue Feb 28 21:31:50 2023 +0000 +commit efde85dda2130272af24cc346f6c3cd326182ff1 +Author: Darren Tucker +Date: Mon Feb 19 17:29:31 2024 +1100 - upstream: fatal out if allocating banner string fails to avoid - - potential null deref later in sscanf. Spotted by Coverity, ok deraadt@ + Improve error message for OpenSSL header check. - OpenBSD-Commit-ID: 74e8d228ac00552e96e9e968dfcccf8dd1f46ad5 + bz#3668, ok djm@ -commit 44ca56ba0b3f531f1d85730cc701097cd49e6868 -Author: dtucker@openbsd.org -Date: Tue Feb 28 08:45:24 2023 +0000 +commit cbbdf868bce431a59e2fa36ca244d5739429408d +Author: Darren Tucker +Date: Wed Feb 7 13:45:02 2024 +1100 - upstream: Explicitly ignore return from fchmod - - similar to other calls to prevent warning. - - OpenBSD-Commit-ID: fdc5287dcee0860b5a493186414226c655b0eb0a + Interop test against PuTTY snapshot and releases. -commit 803392933a3a6f09f834aa5f0c2aab06a3b382f4 -Author: dtucker@openbsd.org -Date: Mon Feb 27 22:12:40 2023 +0000 +commit 91898bf786b0f149f962c4c96c08a46f29888c10 +Author: Darren Tucker +Date: Tue Feb 6 16:21:05 2024 +1100 - upstream: Plug mem leak on globbed ls error path. - - Spotted by Coverity, ok deraadt@ + Put privsep dir on OS X on /usr/local. - OpenBSD-Commit-ID: de28476025db29820a9a2e56e98b964d8a02861c + On some runners we can't create /var/empty, so put it some place we can + write. Should fix test breakage on Max OS X 11. -commit aa33b4d396abf47a2a45f982f28d054fb1dcb5c3 +commit be5ed8ebed8388c5056bfde4688308cc873c18b9 Author: Darren Tucker -Date: Mon Feb 27 21:04:22 2023 +1100 +Date: Tue Feb 6 11:19:42 2024 +1100 - Cast time_t's in debug output to long long. + Add --disable-fd-passing option. - Should fix Coverity warning about truncation of 64bit time_t. + .. and enable for the minix3 test VM. This will cause it to more reliably + skip tests that need FD passing and should fix the current test breakage. -commit b0fd60a9de62a03189ad57d0c07f0ac51dc00e95 +commit 0f6a8a0d0a518fd78c4cbebfdac990a57a1c4e41 Author: Darren Tucker -Date: Mon Feb 27 17:28:59 2023 +1100 +Date: Tue Feb 6 11:18:44 2024 +1100 - Do shadow expiry calcs using "long long". - - Coverity flags these as potentially not 64bit time_t safe so use - long long for the calculations and debug output. ok djm@ + Use "skip" function instead doing it ourselves. -commit 01dbeb3084d714bbd001ff9d03b9de542e8cdf58 +commit 3ad669f81aabbd2ba9fbd472903f680f598e1e99 Author: Damien Miller -Date: Mon Feb 27 17:07:52 2023 +1100 +Date: Thu Feb 1 14:01:18 2024 +1100 - avoid clash between for getopt's struct option - - Since we don't use getopt_long() nothing outside the getopt() - implementation itself uses this structure, so move it into the - source to remove it from visibility and clashes with libc's - - ok dtucker@ + ignore some vim droppings -commit eb88d07c43afe407094e7d609248d85a15e148ef -Author: Darren Tucker -Date: Sat Feb 25 14:45:41 2023 +1100 +commit c283f29d23611a06bbee06bcf458f2fffad721d9 +Author: djm@openbsd.org +Date: Thu Feb 1 02:37:33 2024 +0000 - Revert explicit chmods on private keys. + upstream: whitespace - This should no longer be needed on Cygwin test runners due to previous - commit. + OpenBSD-Commit-ID: bf9e4a1049562ee4322684fbdce07142f04fdbb7 -commit 52b75db61030a6c8baf66b73644380cf3f58e26a -Author: Darren Tucker -Date: Sat Feb 25 14:43:28 2023 +1100 +commit 0d96b1506b2f4757fefa5d1f884d49e96a6fd4c3 +Author: Damien Miller +Date: Tue Jan 16 14:40:18 2024 +1100 - Remove extended ACLs from working dirs. + skip tests that use multiplexing on Windows - This should allow umask to work as expected and prevent tests from - failing due to excessive permissions on private keys. + Some tests here use multiplexing, skip these if DISABLE_FD_PASSING + is set. Should unbreak tests on Windows. -commit 0c5d4c843df5605b043a758d69f9a611ef63c479 -Author: Darren Tucker -Date: Fri Feb 24 13:44:13 2023 +1100 +commit 50080fa42f5f744b798ee29400c0710f1b59f50e +Author: djm@openbsd.org +Date: Thu Jan 11 04:50:28 2024 +0000 - Explicitly set permissions on user and host keys. + upstream: don't disable RSA test when DSA is disabled; bug introduced + + in last commit - On cygwin, the umask might not be sufficient. Should fix tests on - Github runners. + OpenBSD-Regress-ID: 8780a7250bf742b33010e9336359a1c516f2d7b5 -commit 6c9fc9d7a9f7abf82c3294d74e6d4a25735862ce +commit 415c94ce17288e0cdcb9e58cc91fba78d33c8457 Author: djm@openbsd.org -Date: Wed Feb 22 03:56:43 2023 +0000 +Date: Thu Jan 11 01:45:58 2024 +0000 - upstream: fix progressmeter corruption on wide displays; bz3534 + upstream: make DSA testing optional, defaulting to on - feedback/ok dtucker@ + ok markus - OpenBSD-Commit-ID: f4affee067cec7c182f3e0b307d758e0472762a3 + OpenBSD-Regress-ID: dfc27b5574e3f19dc4043395594cea5f90b8572a -commit fe0bd3cde9665d364e5eedd2c2c2e60d4cdc3786 -Author: dtucker@openbsd.org -Date: Tue Feb 21 06:48:18 2023 +0000 +commit f9311e8921d92c5efca767227a497ab63280ac39 +Author: djm@openbsd.org +Date: Thu Jan 11 01:51:16 2024 +0000 - upstream: fseek to end of known_hosts before writing to it. + upstream: ensure key_fd is filled when DSA is disabled; spotted by - POSIX and ANSI C require that applications call fseek or similar between - read and writing to a RW file. OpenBSD doesn't enforce this, but some - (System V derived) platforms need this to prevent it from writing a - spurious extra byte (in this case, a newline). ok djm@ deraadt@ + tb@ - OpenBSD-Commit-ID: 33e680dcd8110582a93a40a8491024e961f45137 + OpenBSD-Commit-ID: 9dd417b6eec3cf67e870f147464a8d93f076dce7 -commit 357fb8ae14c07cd025eeed66e73de91bab569849 -Author: Darren Tucker -Date: Tue Feb 21 17:51:09 2023 +1100 +commit 4e838120a759d187b036036610402cbda33f3203 +Author: djm@openbsd.org +Date: Thu Jan 11 01:45:36 2024 +0000 - Also run unit tests on AIX VMs. + upstream: make DSA key support compile-time optional, defaulting to + + on - In the past these tests took too long, but these days it only adds - about 5 min to the run. + ok markus@ + + OpenBSD-Commit-ID: 4f8e98fc1fd6de399d0921d5b31b3127a03f581d -commit 17781aaa5188ee1477f7779b280d105512e3dbed -Author: Darren Tucker -Date: Tue Feb 21 17:38:55 2023 +1100 +commit afcc9028bfc411bc26d20bba803b83f90cb84e26 +Author: jmc@openbsd.org +Date: Wed Jan 10 06:33:13 2024 +0000 - Wrap stdint.h inside ifdef. + upstream: fix incorrect capitalisation; + + OpenBSD-Commit-ID: cb07eb06e15fa2334660ac73e98f29b6a1931984 -commit ef798bad38505f7bf1b5fa5c0843dfc5a2b192b9 -Author: Mayank Sharma -Date: Mon Feb 20 17:37:15 2023 +0530 +commit 9707c8170c0c1baeb1e06e5a53f604498193885f +Author: djm@openbsd.org +Date: Tue Jan 9 22:19:36 2024 +0000 - Add includes to ptimeout test. + upstream: extend ChannelTimeout regression test to exercise multiplexed + + connections and the new "global" timeout type. ok dtucker@ - Fixes test failures on AIX due to type mismatches. + OpenBSD-Regress-ID: f10d19f697024e9941acad7c2057f73d6eacb8a2 -commit ab69dda05d5268454209f529fa80f477e60d846a -Author: Darren Tucker -Date: Mon Feb 20 18:24:39 2023 +1100 +commit b31b12d28de96e1d43581d32f34da8db27e11c03 +Author: djm@openbsd.org +Date: Tue Jan 9 22:19:00 2024 +0000 - Always use the openssl binary configure tells us. + upstream: add a "global" ChannelTimeout type to ssh(1) and sshd(8) - This fixes tests on platforms that do not have the openssl tool - installed at all. - -commit 2a7e3449908571af601a4c2d12ab140096442e47 -Author: dtucker@openbsd.org -Date: Fri Feb 17 04:22:50 2023 +0000 - - upstream: Remove now-unused compat bit SSH_BUG_RSASIGMD5. The code + that watches all open channels and will close all open channels if there is + no traffic on any of them for the specified interval. This is in addition to + the existing per-channel timeouts added a few releases ago. + + This supports use-cases like having a session + x11 forwarding channel + open where one may be idle for an extended period but the other is + actively used. The global timeout would allow closing both channels when + both have been idle for too long. - to set this was removed in OpenSSH 7.7 when support for SSH implementations - dating back to before RFC standardization were removed. "burn it all" djm@ + ok dtucker@ - OpenBSD-Commit-ID: 6330935fbe23dd00be79891505e06d1ffdac7cda + OpenBSD-Commit-ID: 0054157d24d2eaa5dc1a9a9859afefc13d1d7eb3 -commit 0833ccf2c8b7ae08b296c06f17bd53e3ab94b0b0 -Author: dtucker@openbsd.org -Date: Fri Feb 17 03:06:18 2023 +0000 +commit 602f4beeeda5bb0eca181f8753d923a2997d0a51 +Author: djm@openbsd.org +Date: Tue Jan 9 21:39:14 2024 +0000 - upstream: Remove now-unused compat bit SSH_BUG_BIGENDIANAES. This + upstream: adapt ssh_api.c code for kex-strict - was previously set for OpenSSH 2.3 (released in 2000) but this check was - removed in OpenSSH 7.7 (2018). ok djm@ deraadt@ + from markus@ ok me - OpenBSD-Commit-ID: 326426ea328707fc9e83305291ab135c87f678af + OpenBSD-Commit-ID: 4d9f256852af2a5b882b12cae9447f8f00f933ac -commit c81c2bea6e828d52b62b448b4ffdd3c163177975 +commit 42ba34aba8708cf96583ff52975d95a8b47d990d Author: Damien Miller -Date: Fri Feb 17 10:12:40 2023 +1100 +Date: Mon Jan 8 16:26:37 2024 +1100 - whitespace fixes + nite that recent OSX tun/tap is unsupported -commit 500f90b39db5f0014e6b0c49ff1f45c994b69293 -Author: Damien Miller -Date: Fri Feb 17 10:02:08 2023 +1100 +commit 690bc125f9a3b20e47745fa8f5b5e1fd5820247f +Author: Sevan Janiyan +Date: Wed Dec 27 04:57:49 2023 +0000 - whitespace at EOL + README.platform: update tuntap url -commit 68350152406339170721c15e97afdf827a5e4001 -Author: dtucker@openbsd.org -Date: Thu Feb 16 10:10:00 2023 +0000 +commit 6b8be2ccd7dd091808f86af52066b0c2ec30483a +Author: Rose <83477269+AtariDreams@users.noreply.github.com> +Date: Tue Dec 19 11:48:20 2023 -0500 - upstream: Remove SSH_BUG_PASSWORDPAD compat bit - - since it's no longer used. ok markus@ + Fix compilation error in ssh-pcks11-client.c - OpenBSD-Commit-ID: b92c21f56fe4b7f9a54790d6a9650725c226820b + Compilation fails becaus of an undefined reference to helper_by_ec, + because we forgot the preprocessor conditional that excludes that function + from being called in unsupported configurations. -commit 537cccd804eaf65f32bdce037cc31db4e0ab0f44 -Author: dtucker@openbsd.org -Date: Thu Feb 16 07:55:15 2023 +0000 +commit 219c8134157744886ee6ac5b8c1650abcd981f4c +Author: djm@openbsd.org +Date: Mon Jan 8 05:11:18 2024 +0000 - upstream: Remove SSH_BUG_IGNOREMSG compat flag + upstream: Remove outdated note from PROTOCOL.mux - since it's only applicable to SSH1 and thus no longer used. ok markus@ - "kill it with fire" djm@ + Port forward close by control master is already implemented + by `mux_master_process_close_fwd` in `mux.c` - OpenBSD-Commit-ID: ea13318b1937795d9db4790d3ce0a6ed01584dab - -commit 285cf6cd4b91a0a0ce33193c358c99085af33e43 -Author: jmc@openbsd.org -Date: Fri Feb 10 06:41:53 2023 +0000 - - upstream: space between macro and punctuation; sort usage(); + GHPR442 from bigb4ng - OpenBSD-Commit-ID: 6141610cfca037700730e41f868d1d9124958f8c + OpenBSD-Commit-ID: ad0734fe5916d2dc7dd02b588906cea4df0482fb -commit d39a96f70f81878c77336ed35f5c648c1804b71a -Author: jmc@openbsd.org -Date: Fri Feb 10 06:40:48 2023 +0000 +commit 4c3cf362631ccc4ffd422e572f075d5d594feace +Author: djm@openbsd.org +Date: Mon Jan 8 05:05:15 2024 +0000 - upstream: space between macro and punctuation; + upstream: fix missing field in users-groups-by-id@openssh.com reply - OpenBSD-Commit-ID: abc95e550be9e6d9a7ff64b65c104c7be21ab19e - -commit 16e82bf53fc34e43e3b948d43b68d5b27a7335e6 -Author: jmc@openbsd.org -Date: Fri Feb 10 06:39:27 2023 +0000 - - upstream: sort SYNOPSIS; + documentation - OpenBSD-Commit-ID: dacd9da33277d5669a51213d880632599c890c1e - -commit d9685121ff6d57b8797411f3cb123884a4b96e30 -Author: Darren Tucker -Date: Sat Feb 11 12:32:19 2023 +1100 - - Improve seccomp compat on older systems. + GHPR441 from TJ Saunders - Check if flags to mmap and madvise are defined before using them. - Should fix problems building on older Linux systems that don't have - these. bz#3537, with & ok djm@. + OpenBSD-Commit-ID: ff5733ff6ef4cd24e0758ebeed557aa91184c674 -commit 6180b0fa4f7996687678702806257e661fd5931e +commit f64cede2a3c298b50a2659a8b53eb3ab2c0b8d23 Author: djm@openbsd.org -Date: Fri Feb 10 05:06:03 2023 +0000 +Date: Mon Jan 8 04:10:03 2024 +0000 - upstream: test -Ohashalg=... and that the default output contains both + upstream: make kex-strict section more explicit about its intent: - specified hash algorithms; prompted by dtucker@ + banning all messages not strictly required in KEX - OpenBSD-Regress-ID: 26f309208c8d8b8fa9c5f419767b85f1e9b22f51 + OpenBSD-Commit-ID: fc33a2d7f3b7013a7fb7500bdbaa8254ebc88116 -commit d651f5c9fe37e61491eee46c49ba9fa03dbc0e6a -Author: djm@openbsd.org -Date: Fri Feb 10 04:56:30 2023 +0000 +commit 698fe6fd61cbcb8e3e0e874a561d4335a49fbde5 +Author: Damien Miller +Date: Mon Jan 8 14:46:19 2024 +1100 - upstream: let ssh-keygen and ssh-keyscan accept - - -Ohashalg=sha1|sha256 when outputting SSHFP fingerprints to allow algorithm - selection. bz3493 ok dtucker@ - - OpenBSD-Commit-ID: e6e07fe21318a873bd877f333e189eb963a11b3d + update fuzzer example makefile to clang16 -commit 18938d11a90b74d63c20b2d3c965d5bd64786ab1 -Author: djm@openbsd.org -Date: Fri Feb 10 04:47:19 2023 +0000 +commit fc332cb2d602c60983a8ec9f89412754ace06425 +Author: Damien Miller +Date: Mon Jan 8 14:45:49 2024 +1100 - upstream: add a `sshd -G` option that parses and prints the - - effective configuration without attempting to load private keys and perform - other checks. This allows usage of the option before keys have been - generated. + unbreak fuzzers - missing pkcs11_make_cert() - bz3460 feedback/ok dtucker@ + provide stub for use in fuzzer harness + +commit 9ea0a4524ae3276546248a926b6641b2fbc8421b +Author: Damien Miller +Date: Mon Jan 8 14:45:14 2024 +1100 + + unbreak fuzzers for clang16 - OpenBSD-Commit-ID: 774504f629023fc25a559ab1d95401adb3a7fb29 + getopt() needs a throw() attribute to compile, so supply one when compiling + things with C++ -commit df7d3dbf7194db8e97730ee0425d4d9d7bdb8b10 +commit a72833d00788ef91100c643536ac08ada46440e1 Author: djm@openbsd.org -Date: Fri Feb 10 04:40:28 2023 +0000 +Date: Mon Jan 8 00:34:33 2024 +0000 - upstream: make `ssh -Q CASignatureAlgorithms` work as the manpage says + upstream: remove ext-info-* in the kex.c code, not in callers; - it should bz3532 + with/ok markus@ - OpenBSD-Commit-ID: 0ddb17b3fcbd99bfb5baea4ac5e449620cbd3adc + OpenBSD-Commit-ID: c06fe2d3a0605c517ff7d65e38ec7b2d1b0b2799 -commit d3b8d4198b6595f23b5859d43dc8fc701f97429b -Author: Darren Tucker -Date: Fri Feb 10 14:26:44 2023 +1100 +commit 86f9e96d9bcfd1f5cd4bf8fb57a9b4c242df67df +Author: djm@openbsd.org +Date: Mon Jan 8 00:30:39 2024 +0000 - Add CentOS 7 test targets. + upstream: fix typo; spotted by Albert Chin + + OpenBSD-Commit-ID: 77140b520a43375b886e535eb8bd842a268f9368 -commit 22efb01e355bba4755b730ed417f91c081445bfc +commit f0cbd26ec91bd49719fb3eea7ca44d2380318b9a Author: dtucker@openbsd.org -Date: Thu Feb 9 09:55:33 2023 +0000 +Date: Thu Jan 4 09:51:49 2024 +0000 - upstream: Test adding terminating newline to known_hosts. + upstream: Import regenerated moduli. - OpenBSD-Regress-ID: 5fc3010ac450195b3fbdeb68e875564968800365 + OpenBSD-Commit-ID: 5a636f6ca7f25bfe775df4952f7aac90a7fcbbee -commit caec6da1a583ed8c32c6ad3b81bbcaab46ac8b61 -Author: dtucker@openbsd.org -Date: Wed Feb 8 08:06:03 2023 +0000 +commit 64ddf776531ca4933832beecc8b7ebe1b937e081 +Author: jsg@openbsd.org +Date: Wed Dec 20 00:06:25 2023 +0000 - upstream: ssh-agent doesn't actually take -v, - - so the recently-added ones will result in the test not cleaning up - after itself. Patch from cjwatson at debian.org vi bz#3536. + upstream: spelling; ok markus@ - OpenBSD-Regress-ID: 1fc8283568f5bf2f918517c2c1e778072cf61b1a + OpenBSD-Commit-ID: 9d01f2e9d59a999d5d42fc3b3efcf8dfb892e31b -commit 3c379c9a849a635cc7f05cbe49fe473ccf469ef9 -Author: dtucker@openbsd.org -Date: Thu Feb 9 09:54:11 2023 +0000 +commit 503fbe9ea238a4637e8778208bde8c09bcf78475 +Author: jmc@openbsd.org +Date: Tue Dec 19 06:57:34 2023 +0000 - upstream: Ensure that there is a terminating newline when adding a new + upstream: sort -C, and add to usage(); ok djm - entry to known_hosts. bz#3529, with git+openssh at limpsquid.nl, ok deraadt@ - markus@ + OpenBSD-Commit-ID: 80141b2a5d60c8593e3c65ca3c53c431262c812f + +commit 5413b1c7ff5a19c6a7d44bd98c5a83eb47819ba6 +Author: djm@openbsd.org +Date: Tue Dec 19 06:41:14 2023 +0000 + + upstream: correct section numbers; from Ed Maste - OpenBSD-Commit-ID: fa8d90698da1886570512b96f051e266eac105e0 + OpenBSD-Commit-ID: e289576ee5651528404cb2fb68945556052cf83f -commit 95b6bbd2553547260b324b39d602061c88b774bc -Author: Darren Tucker -Date: Tue Feb 7 08:43:47 2023 +1100 +commit 430ef864645cff83a4022f5b050174c840e275da +Author: djm@openbsd.org +Date: Mon Dec 18 15:58:56 2023 +0000 - Replace 9.1 with 9.2 on CI status page. + upstream: match flag type (s/int/u_int) + + OpenBSD-Commit-ID: 9422289747c35ccb7b31d0e1888ccd5e74ad566a -commit 195313dfe10a23c82e9d56d5fdd2f59beee1bdcf +commit 1036d77b34a5fa15e56f516b81b9928006848cbd Author: Damien Miller -Date: Fri Feb 3 16:33:09 2023 +1100 +Date: Fri Dec 22 17:56:26 2023 +1100 - harden Linux seccomp sandbox + better detection of broken -fzero-call-used-regs - Linux mmap(2) and madvise(2) syscalls support quite a number of funky - flags that we don't expect that sshd/libc will ever need. We can - exclude this kernel attack surface by filtering the mmap(2) flags - and the madvise(2) advice arguments. + gcc 13.2.0 on ppc64le refuses to compile some function, including + cipher.c:compression_alg_list() with an error: - Similarly, the sandboxed process in sshd is a single-threaded program - that does not use shared memory for synchronisation or communication. - Therefore, there should be no reason for the advanced priority - inheritance futex(2) operations to be necessary. These can also be - excluded. + > sorry, unimplemented: argument ‘used’ is not supportedcw + > for ‘-fzero-call-used-regs’ on this target - Motivated by Jann Horn pointing out that there have been kernel bugs - in nearby Linux kernel code, e.g. CVE-2020-29368, CVE-2020-29374 and - CVE-2022-42703. + This extends the autoconf will-it-work test with a similarly- + structured function that seems to catch this. - Feedback Jann Horn, ok dtucker@ - -commit 6dfb65de949cdd0a5d198edee9a118f265924f33 -Author: Damien Miller -Date: Thu Feb 2 23:21:54 2023 +1100 - - crank versions in RPM specs + Spotted/tested by Colin Watson; bz3645 -commit d07cfb11a0ca574eb68a3931d8c46fbe862a2021 +commit 8241b9c0529228b4b86d88b1a6076fb9f97e4a99 Author: Damien Miller -Date: Thu Feb 2 23:21:45 2023 +1100 +Date: Tue Dec 19 01:59:50 2023 +1100 - update version in README + crank versions -commit 9fe207565b4ab0fe5d1ac5bb85e39188d96fb214 +commit 2f2c65cb5f1518a9c556d3e8efa27ea0ca305c6b Author: Damien Miller -Date: Thu Feb 2 23:17:49 2023 +1100 +Date: Tue Dec 19 01:59:06 2023 +1100 - adapt compat_kex_proposal() test to portable + depend -commit 903c556b938fff2d7bff8da2cc460254430963c5 +commit e48cdee8e19059203b1aeeabec2350b8375fa61f Author: djm@openbsd.org -Date: Thu Feb 2 12:12:52 2023 +0000 +Date: Mon Dec 18 14:50:08 2023 +0000 - upstream: test compat_kex_proposal(); by dtucker@ + upstream: regress test for agent PKCS#11-backed certificates - OpenBSD-Regress-ID: 0e404ee264db546f9fdbf53390689ab5f8d38bf2 + OpenBSD-Regress-ID: 38f681777cb944a8cc3bf9d0ad62959a16764df9 -commit 405fba71962dec8409c0c962408e09049e5624b5 -Author: dtucker@openbsd.org -Date: Thu Jan 19 07:53:45 2023 +0000 +commit 2f512f862df1d5f456f82a0334c9e8cc7208a2a1 +Author: djm@openbsd.org +Date: Mon Dec 18 14:49:39 2023 +0000 - upstream: Check if we can copy sshd or need to use sudo to do so - - during reexec test. Skip test if neither can work. Patch from anton@, tweaks - from me. + upstream: regress test for constrained PKCS#11 keys - OpenBSD-Regress-ID: 731b96ae74d02d5744e1f1a8e51d09877ffd9b6d + OpenBSD-Regress-ID: b2f26ae95d609d12257b43aef7cd7714c82618ff -commit b2a2a8f69fd7737ea17dc044353c514f2f962f35 +commit cdddd66412ca5920ed4d3ebbfa6ace12dbd9b82f Author: djm@openbsd.org -Date: Thu Feb 2 12:10:22 2023 +0000 +Date: Mon Dec 18 14:48:44 2023 +0000 - upstream: openssh-9.2 + upstream: openssh-9.6 - OpenBSD-Commit-ID: f7389f32413c74d6e2055f05cf65e7082de03923 + OpenBSD-Commit-ID: 21759837cf0e0092d9a2079f8fb562071c11016b -commit 12da7823336434a403f25c7cc0c2c6aed0737a35 +commit 6d51feab157cedf1e7ef5b3f8781ca8ff9c4ab1b Author: djm@openbsd.org -Date: Thu Feb 2 12:10:05 2023 +0000 +Date: Mon Dec 18 14:48:08 2023 +0000 - upstream: fix double-free caused by compat_kex_proposal(); bz3522 + upstream: ssh-agent: record failed session-bind attempts - by dtucker@, ok me + Record failed attempts to session-bind a connection and refuse signing + operations on that connection henceforth. - OpenBSD-Commit-ID: 2bfc37cd2d41f67dad64c17a64cf2cd3806a5c80 - -commit 79efd95ab5ff99f4cb3a955e2d713b3f54fb807e -Author: Darren Tucker -Date: Wed Feb 1 17:17:26 2023 +1100 - - Skip connection-timeout test on minix3. + Prevents a future situation where we add a new hostkey type that is not + recognised by an older ssh-agent, that consequently causes session-bind + to fail (this situation is only likely to arise when people mix ssh(1) + and ssh-agent(1) of different versions on the same host). Previously, + after such a failure the agent socket would be considered unbound and + not subject to restriction. - Minix 3's Unix domain sockets don't seem to work the way we expect, so - skip connection-timeout test on that platform. While there, group - together all similarly skipped tests and explicitly comment. - -commit 6b508c4e039619842bcf5a16f8a6b08dd6bec44a -Author: Damien Miller -Date: Wed Feb 1 12:12:05 2023 +1100 - - fix libfido2 detection without pkg-config + Spotted by Jann Horn - Place libfido2 before additional libraries (that it may depend upon) - and not after. bz3530 from James Zhang; ok dtucker@ + OpenBSD-Commit-ID: b0fdd023e920aa4831413f640de4c5307b53552e -commit 358e300fed5e6def233a2c06326e51e20ebed621 -Author: deraadt@openbsd.org -Date: Wed Jan 18 20:56:36 2023 +0000 +commit 7ef3787c84b6b524501211b11a26c742f829af1a +Author: djm@openbsd.org +Date: Mon Dec 18 14:47:44 2023 +0000 - upstream: delete useless dependency + upstream: ban user/hostnames with most shell metacharacters - OpenBSD-Commit-ID: e1dc11143f83082e3154d6094f9136d0dc2637ad - -commit a4cb9be1b021b511e281ee55c356f964487d9e82 -Author: deraadt@openbsd.org -Date: Wed Jan 18 20:43:15 2023 +0000 - - upstream: Create and install sshd random relink kit. + This makes ssh(1) refuse user or host names provided on the + commandline that contain most shell metacharacters. + + Some programs that invoke ssh(1) using untrusted data do not filter + metacharacters in arguments they supply. This could create + interactions with user-specified ProxyCommand and other directives + that allow shell injection attacks to occur. - ../Makefile.inc and Makfile are concatenated for reuse, which hopefully won't - be too fragile, we'll see if we need a different approach. The resulting sshd - binary is tested with the new sshd -V option before installation. As the - binary layout is now semi-unknown (meaning relative, fixed, and gadget - offsets are not precisely known), change the filesystem permissions to 511 to - prevent what I call "logged in BROP". I have ideas for improving this further - but this is a first step ok djm + It's a mistake to invoke ssh(1) with arbitrary untrusted arguments, + but getting this stuff right can be tricky, so this should prevent + most obvious ways of creating risky situations. It however is not + and cannot be perfect: ssh(1) has no practical way of interpreting + what shell quoting rules are in use and how they interact with the + user's specified ProxyCommand. - OpenBSD-Commit-ID: 1e0a2692b7e20b126dda60bf04999d1d30d959d8 - -commit bc7de6f91a9a0ae2f148a9d31a4027d441a51999 -Author: jmc@openbsd.org -Date: Wed Jan 18 06:55:32 2023 +0000 - - upstream: tweak previous; ok djm + To allow configurations that use strange user or hostnames to + continue to work, this strictness is applied only to names coming + from the commandline. Names specified using User or Hostname + directives in ssh_config(5) are not affected. + + feedback/ok millert@ markus@ dtucker@ deraadt@ - OpenBSD-Commit-ID: df71ce4180c58202dfdc1d92626cfe900b91b7c3 + OpenBSD-Commit-ID: 3b487348b5964f3e77b6b4d3da4c3b439e94b2d9 -commit a20b7e999773e6333c8aa9b0a7fa41966e63b037 -Author: Darren Tucker -Date: Tue Jan 31 19:35:44 2023 +1100 +commit 0cb50eefdd29f0fec31d0e71cc4b004a5f704e67 +Author: djm@openbsd.org +Date: Mon Dec 18 14:47:20 2023 +0000 - Skip connection-timeout test under Valgrind. + upstream: stricter handling of channel window limits + + This makes ssh/sshd more strict in handling non-compliant peers that + send more data than the advertised channel window allows. Previously + the additional data would be silently discarded. This change will + cause ssh/sshd to terminate the connection if the channel window is + exceeded by more than a small grace allowance. - Valgrind slows things down so much that the timeout test fails. Skip - this test until we figure out if we can make it work. + ok markus@ + + OpenBSD-Commit-ID: 811e21b41831eba3dd7f67b3d409a438f20d3037 -commit c3ffb54b4fc5e608206037921db6ccbc2f5ab25f -Author: Darren Tucker -Date: Wed Jan 25 21:58:40 2023 +1100 +commit 4448a2938abc76e6bd33ba09b2ec17a216dfb491 +Author: djm@openbsd.org +Date: Mon Dec 18 14:46:56 2023 +0000 - Skip connection-timeout when missing FD passing. + upstream: Make it possible to load certs from PKCS#11 tokens + + Adds a protocol extension to allow grafting certificates supplied by + ssh-add to keys loaded from PKCS#11 tokens in the agent. + + feedback/ok markus@ - This tests uses multiplexing which uses file descriptor passing, so - skip it if we don't have that. Fixes test failures on Cygwin. + OpenBSD-Commit-ID: bb5433cd28ede2bc910996eb3c0b53e20f86037f -commit 35253af01d8c0ab444c8377402121816e71c71f5 +commit 881d9c6af9da4257c69c327c4e2f1508b2fa754b Author: djm@openbsd.org -Date: Wed Jan 18 02:00:10 2023 +0000 +Date: Mon Dec 18 14:46:12 2023 +0000 - upstream: when restoring non-blocking mode to stdio fds, restore + upstream: apply destination constraints to all p11 keys - exactly the flags that ssh started with and don't just clobber them with - zero, as this could also remove the append flag from the set; + Previously applied only to the first key returned from each token. - bz3523; ok dtucker@ + ok markus@ - OpenBSD-Commit-ID: 1336b03e881db7564a4b66014eb24c5230e9a0c0 + OpenBSD-Commit-ID: 36df3afb8eb94eec6b2541f063d0d164ef8b488d -commit 7d17ea151c0b2519f023bd9cc7f141128833ac47 -Author: millert@openbsd.org -Date: Wed Jan 18 01:50:21 2023 +0000 +commit a7ed931caeb68947d30af8a795f4108b6efad761 +Author: djm@openbsd.org +Date: Mon Dec 18 14:45:49 2023 +0000 - upstream: Add a -V (version) option to sshd like the ssh client + upstream: add "ext-info-in-auth@openssh.com" extension - has. OK markus@ deraadt@ + This adds another transport protocol extension to allow a sshd to send + SSH2_MSG_EXT_INFO during user authentication, after the server has + learned the username that is being logged in to. - OpenBSD-Commit-ID: abe990ec3e636fb040132aab8cbbede98f0c413e - -commit 62360feb7f08f2a4c6fc36f3b3449309203c42c9 -Author: millert@openbsd.org -Date: Tue Jan 17 18:52:44 2023 +0000 - - upstream: For "ssh -V" always exit 0, there is no need to check opt + This lets sshd to update the acceptable signature algoritms for public + key authentication, and allows these to be varied via sshd_config(5) + "Match" directives, which are evaluated after the server learns the + username being authenticated. - again. This was missed when the fallthrough in the switch case above it was - removed. OK deraadt@ + Full details in the PROTOCOL file - OpenBSD-Commit-ID: 5583e5d8f6d62a8a4215cfa95a69932f344c8120 + OpenBSD-Commit-ID: 1de7da7f2b6c32a46043d75fcd49b0cbb7db7779 -commit 12492c0abf1eb415d08a897cc1d8b9e789888230 +commit 1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5 Author: djm@openbsd.org -Date: Tue Jan 17 10:15:10 2023 +0000 +Date: Mon Dec 18 14:45:17 2023 +0000 - upstream: also check that an active session inhibits + upstream: implement "strict key exchange" in ssh and sshd - UnusedConnectionTimeout idea markus@ + This adds a protocol extension to improve the integrity of the SSH + transport protocol, particular in and around the initial key exchange + (KEX) phase. - OpenBSD-Regress-ID: 55c0fb61f3bf9e092b0a53f9041d3d2012f14003 - -commit cef2593c33ac46a58238ff998818754eabdf64ff -Author: djm@openbsd.org -Date: Tue Jan 17 10:02:34 2023 +0000 - - upstream: regression test for UnusedConnectionTimeout + Full details of the extension are in the PROTOCOL file. + + with markus@ - OpenBSD-Regress-ID: 7f29001374a68e71e5e078f69e4520cf4bcca084 + OpenBSD-Commit-ID: 2a66ac962f0a630d7945fee54004ed9e9c439f14 -commit aff9493a89c71d6a080419b49ac64eead9730491 -Author: djm@openbsd.org -Date: Mon Jan 16 04:11:29 2023 +0000 +commit 59d691b886c79e70b1d1c4ab744e81fd176222fd +Author: Damien Miller +Date: Mon Dec 18 14:49:11 2023 +1100 - upstream: unbreak test: cannot access shell positional parameters + better detection of broken -fzero-call-used-regs - past $9 without wrapping the position in braces (i.e. need ${10}, etc.) + Use OSSH_CHECK_CFLAG_LINK() for detection of these flags and extend + test program to exercise varargs, which seems to catch more stuff. - OpenBSD-Regress-ID: 3750ec98d5d409ce6a93406fedde6f220d2ea2ac + ok dtucker@ -commit 0293c19807f83141cdf33b443154459f9ee471f6 +commit aa7b21708511a6d4aed3839fc9f6e82e849dd4a1 Author: djm@openbsd.org -Date: Tue Jan 17 09:44:48 2023 +0000 +Date: Wed Dec 13 03:28:19 2023 +0000 - upstream: Add a sshd_config UnusedConnectionTimeout option to terminate + upstream: when invoking KnownHostsCommand to determine the order of - client connections that have no open channels for some length of time. This - complements the recently-added ChannelTimeout option that terminates inactive - channels after a timeout. + host key algorithms to request, ensure that the hostname passed to the + command is decorated with the port number for ports other than 22. - ok markus@ + This matches the behaviour of KnownHostsCommand when invoked to look + up the actual host key. + + bz3643, ok dtucker@ - OpenBSD-Commit-ID: ca983be74c0350364c11f8ba3bd692f6f24f5da9 + OpenBSD-Commit-ID: 5cfabc0b7c6c7ab473666df314f377b1f15420b1 -commit 8ec2e3123802d2beeca06c1644b0b647f6d36dab -Author: djm@openbsd.org -Date: Sun Jan 15 23:35:10 2023 +0000 +commit 4086bd6652c0badccc020218a62190a7798fb72c +Author: markus@openbsd.org +Date: Fri Dec 8 09:18:39 2023 +0000 - upstream: adapt to ed25519 changes in src/usr.bin/ssh + upstream: prevent leak in sshsig_match_principals; ok djm@ - OpenBSD-Regress-ID: 4b3e7ba7ee486ae8a0b4790f8112eded2bb7dcd5 + OpenBSD-Commit-ID: 594f61ad4819ff5c72dfe99ba666a17f0e1030ae -commit 9fbbfeca1ce4c7ec0001c827bbf4189a3ba0964b +commit 19d3ee2f3adf7d9a606ff015c1e153744702c4c9 Author: djm@openbsd.org -Date: Sun Jan 15 23:05:32 2023 +0000 +Date: Wed Dec 6 21:06:48 2023 +0000 - upstream: update OpenSSH's Ed25519 code to the last version of SUPERCOP - - (20221122) and change the import approach to the same one we use for - Streamlined NTRUPrime: use a shell script to extract the bits we need from - SUPERCOP, make some minor adjustments and squish them all into a single file. + upstream: short circuit debug log processing early if we're not going - ok tb@ tobhe@ + to log anything. From Kobe Housen - OpenBSD-Commit-ID: 1bc0fd624cb6af440905b8ba74ac7c03311b8e3b + OpenBSD-Commit-ID: 2bcddd695872a1bef137cfff7823044dcded90ea -commit 6283f4bd83eee714d0f5fc55802eff836b06fea8 +commit 947affad4831df015c498c00c6351ea6f13895d5 Author: Darren Tucker -Date: Sat Jan 14 22:02:44 2023 +1100 +Date: Mon Nov 27 09:37:28 2023 +1100 - Allow writev is seccomp sandbox. - - This seems to be used by recent glibcs at least in some configurations. - From bz#3512, ok djm@ + Add tests for OpenSSL 3.2.0 and 3.2 stable branch. -commit 923c3f437f439cfca238fba37e97a7041782f615 -Author: dtucker@openbsd.org -Date: Sat Jan 14 10:05:54 2023 +0000 +commit 747dce36206675ca6b885010a835733df469351b +Author: Darren Tucker +Date: Sat Nov 25 09:03:38 2023 +1100 - upstream: Shell syntax fix. From ren mingshuai vi github PR#369. + Use non-zero arg in compiler test program. - OpenBSD-Regress-ID: 6696b2eeefe128099fc3d7ea9f23252cc35156f9 + Now that we're running the test program, passing zero to the test function + can cause divide-by-zero exceptions which might show up in logs. -commit 4d87a00f704e0365e11c3c38b170c1275ec461fc +commit 3d44a5c56585d1c351dbc006240a591b6da502b1 Author: dtucker@openbsd.org -Date: Sat Jan 14 09:57:08 2023 +0000 +Date: Fri Nov 24 00:31:30 2023 +0000 - upstream: Instead of skipping the all-tokens test if we don't have - - OpenSSL (since we use it to compute the hash), put the hash at the end and - just omit it if we don't have it. Prompted by bz#3521. + upstream: Plug mem leak of msg when processing a quit message. - OpenBSD-Regress-ID: c79ecba64250ed3b6417294b6c965e6b12ca5eea - -commit b05406d6f93b8c8ec11ec8b27e7c76cc7a5a55fb -Author: jmc@openbsd.org -Date: Fri Jan 13 07:13:40 2023 +0000 - - upstream: fix double phrase in previous; + Coverity CID#427852, ok djm@ - OpenBSD-Commit-ID: 671e6c8dc5e9230518b2bbfa143daaa88adc66c2 + OpenBSD-Commit-ID: bf85362addbe2134c3d8c4b80f16601fbff823b7 -commit 40564812b659c530eb1f4b62d09e85612aef3107 +commit 1d7f9b6e297877bd00973e6dc5c0642dbefc3b5f Author: dtucker@openbsd.org -Date: Fri Jan 13 03:16:29 2023 +0000 +Date: Thu Nov 23 03:37:05 2023 +0000 - upstream: Document "UserKnownHostsFile none". ok djm@ + upstream: Include existing mux path in debug message. - OpenBSD-Commit-ID: f695742d39e34ecdcc3c861c3739a84648a4bce5 + OpenBSD-Commit-ID: 1c3641be10c2f4fbad2a1b088a441d072e18bf16 -commit d03e245e034019a37388f6f5f893ce848ab6d2e2 +commit f29934066bd0e561a2e516b7e584fb92d2eedee0 Author: Darren Tucker -Date: Fri Jan 13 23:02:34 2023 +1100 +Date: Thu Nov 23 19:41:27 2023 +1100 - Retry package installation 3 times. + Add an Ubuntu 22.04 test VM. - When setting up the CI environment, retry package installation 3 times - before going up. Should help prevent spurious failures during - infrastructure issues. + This is the same version as Github's runners so most of the testing on + it is over there, but having a local VM makes debugging much easier. -commit 625f6bc39840167dafb3bf5b6a3e18503ac986e8 -Author: dtucker@openbsd.org -Date: Fri Jan 13 04:47:34 2023 +0000 +commit a93284a780cd3972afe5f89086b75d564ba157f3 +Author: Darren Tucker +Date: Thu Nov 23 19:36:22 2023 +1100 - upstream: Move scp path setting to a helper function. The previous - - commit to add scp to the test sshd's path causes the t-envpass test to fail - when the test scp is given using a fully qualified path. Put this in a - helper function and only call it from the scp tests. + Add gcc-12 -Werror test on Ubuntu 22.04. - OpenBSD-Regress-ID: 7533dc1c4265c1de716abb062957994195b36df4 + Explictly specify gcc-11 on Ubuntu 22.04 (it's the system compiler). -commit 6e6f88647042b3cde54a628545c2f5fb656a9327 -Author: dtucker@openbsd.org -Date: Fri Jan 13 04:23:00 2023 +0000 +commit 670f5a647e98b6fd95ad64f789f87ee3274b481b +Author: Darren Tucker +Date: Thu Nov 23 19:34:57 2023 +1100 - upstream: Add scp's path to test sshd's PATH. - - If the scp we're testing is fully qualified (eg it's not in the system - PATH) then add its path to the under-test sshd's PATH so we can find - it. Prompted by bz#3518. + Check return value from write to prevent warning. - OpenBSD-Regress-ID: 7df4f5a0be3aa135495b7e5a6719d3cbc26cc4c0 + ... and since we're testing for flags with -Werror, this caused + configure to mis-detect compiler flags. -commit 8a5e99a70fcf9b022a8aa175ebf6a71f58511da3 +commit cea007d691cfedfa07a5b8599f97ce0511f53fc9 Author: Darren Tucker -Date: Fri Jan 13 15:49:48 2023 +1100 +Date: Wed Nov 22 21:18:55 2023 +1100 - Remove skipping test when scp not in path. + Run compiler test program when compiling natively. - An upcoming change renders this obsolete by adding scp's path to the - test sshd's PATH, and removing this first will make the subsequent sync - easier. + ok djm@ -commit 41f36dd896c8fb8337d403fcf476762986976e9d -Author: dtucker@openbsd.org -Date: Fri Jan 13 02:58:20 2023 +0000 +commit ee0d305828f13536c0a416bbf9c3e81039d9ea55 +Author: Darren Tucker +Date: Wed Nov 22 21:18:07 2023 +1100 - upstream: Add a "Host" line to the output of ssh -G showing the + Factor out compiler test program into a macro. - original host arg. Inspired by patch from vincent at bernat.ch via bz#3343, ok djm@ - - OpenBSD-Commit-ID: 59c0f60a222113a44d0650cd394376e3beecc883 -commit f673b49f3be3eb51074fbb8a405beb6cd0f7d93e -Author: djm@openbsd.org -Date: Fri Jan 13 02:44:02 2023 +0000 +commit de304c76316b029df460673725a9104224b9959b +Author: Darren Tucker +Date: Wed Nov 22 08:55:36 2023 +1100 - upstream: avoid printf("%s", NULL) if using ssh - - -oUserKnownHostsFile=none and a hostkey in one of the system known hosts file - changes; ok dtucker@ - - OpenBSD-Commit-ID: 7ca87614bfc6da491315536a7f2301434a9fe614 + Add fbsd14 VM to test pool. -commit 93fc7c576563e3d88a1dc019dd213f65607784cc -Author: djm@openbsd.org -Date: Wed Jan 11 05:39:38 2023 +0000 +commit 99a2df5e1994cdcb44ba2187b5f34d0e9190be91 +Author: Darren Tucker +Date: Tue Nov 21 16:19:29 2023 +1100 - upstream: clamp the minimum buffer lengths and number of inflight - - requests too + Expand -fzero-call-used-regs test to cover gcc 11. - OpenBSD-Commit-ID: c4965f62fa0ba850940fd66ae3f60cf516bbcd56 + It turns out that gcc also has some problems with -fzero-call-used-regs, + at least v11 on mips. Previously the test in OSSH_CHECK_CFLAG_COMPILE + was sufficient to catch it with "=all", but not sufficient for "=used". + Expand the testcase and include it in the other tests for good measure. + See bz#3629. ok djm@. -commit 48bf234322e639d279c5a28435eae50155e9b514 -Author: djm@openbsd.org -Date: Wed Jan 11 05:36:50 2023 +0000 +commit ff220d4010717f7bfbbc02a2400666fb9d24f250 +Author: Darren Tucker +Date: Tue Nov 21 14:04:34 2023 +1100 - upstream: ignore bogus upload/download buffer lengths in the limits - - extension + Stop using -fzero-call-used-regs=all - OpenBSD-Commit-ID: c5b023e0954693ba9a5376e4280c739b5db575f8 + ... since it seems to be problematic with several different versions of + clang. Only use -fzero-call-used-regs=used which is less + problematic, except with Apple's clang where we don't use it at all. + bz#3629, ok djm@ -commit 36b00d31833ca74cb0f7c7d8eda1bde55700f929 -Author: djm@openbsd.org -Date: Wed Jan 11 02:13:52 2023 +0000 +commit 2a19e02f36b16f0f6cc915f7d1e60ead5e36303b +Author: Darren Tucker +Date: Tue Nov 21 14:02:18 2023 +1100 - upstream: remove whitespace at EOL from code extracted from SUPERCOP + Allow for vendor prefix on clang version numbers. - OpenBSD-Commit-ID: 1ec524ff2fbb9387d731601437c82008f35a60f4 + Correctly detects the version of OpenBSD's native clang, as well as + Apple's. Spotted tb@, ok djm@. -commit d888de06c5e4d7dbf2f2b85f2b5bf028c570cf78 +commit c52db0114826d73eff6cdbf205e9c1fa4f7ca6c6 Author: djm@openbsd.org -Date: Wed Jan 11 00:51:27 2023 +0000 - - upstream: rewrite this test to use a multiplexed ssh session so we can - - control its lifecycle without risk of race conditions; fixes some of the - Github integration tests for openssh-portable - - OpenBSD-Regress-ID: 5451cad59ba0d43ae9eeda48ec80f54405fee969 - -commit 4bcc737a35fdd9cc4af7423d6c23dfd0c7ef4786 -Author: Damien Miller -Date: Wed Jan 11 11:45:17 2023 +1100 +Date: Mon Nov 20 02:50:00 2023 +0000 - remove buffer len workaround for NetBSD 4.x + upstream: set errno=EAFNOSUPPORT when filtering addresses that don't - Switching to from pipes to a socketpair for communicating with the - ssh process avoids the (kernel bug?) problem. - -commit f5154d2aac3e6a32a1b13dec23a701a087850cdc -Author: Damien Miller -Date: Wed Jan 11 11:44:19 2023 +1100 - - add back use of pipes in scp.c under USE_PIPES + match AddressFamily; yields slightly better error message if no address + matches. bz#3526 - This matches sftp.c which prefers socketpair but uses pipes on - some older platforms. + OpenBSD-Commit-ID: 29cea900ddd8b04a4d1968da5c4a893be2ebd9e6 -commit eec737b59cf13841de46134967a206607000acd4 -Author: millert@openbsd.org -Date: Tue Jan 10 23:22:15 2023 +0000 +commit 26f3f3bbc69196d908cad6558c8c7dc5beb8d74a +Author: djm@openbsd.org +Date: Wed Nov 15 23:03:38 2023 +0000 - upstream: Switch scp from using pipes to a socketpair for + upstream: when connecting via socket (the default case), filter - communication with it's ssh sub-processes. We no longer need to reserve two - descriptors to ensure that we don't end up using fd 0-2 unexpectedly, that is - handled by sanitise_stdfd() in main(). Based on an original diff from djm@. - OK deraadt@ djm@ + addresses by AddressFamily if one was specified. Fixes the case where, if + CanonicalizeHostname is enabled, ssh may ignore AddressFamily. bz5326; ok + dtucker - OpenBSD-Commit-ID: b80c372faac462471e955ddeab9480d668a2e48d + OpenBSD-Commit-ID: 6c7d7751f6cd055126b2b268a7b64dcafa447439 -commit d213d126a4a343abd3a1eb13687d39c1891fe5c8 -Author: jmc@openbsd.org -Date: Fri Jan 6 08:44:11 2023 +0000 +commit 050c335c8da43741ed0df2570ebfbd5d1dfd0a31 +Author: djm@openbsd.org +Date: Wed Nov 15 22:51:49 2023 +0000 - upstream: tweak previous; ok djm + upstream: when deciding whether to enable keystroke timing - OpenBSD-Commit-ID: 229c493452766d70a78b0f02f6ff9894f9028858 - -commit 4a5590a5ee47b7dfd49773e9fdba48ad3089fe64 -Author: Damien Miller -Date: Mon Jan 9 16:33:56 2023 +1100 - - try to improve logging for dynamic-forward test + obfuscation, only consider enabling it when a channel with a tty is open. - previously the logs from the ssh used to exercise the forwarding - channel would clobber the logs from the ssh actually doing the - forwarding - -commit 715bc25dcfccf9fb2bee820155fe071d01a618db -Author: Darren Tucker -Date: Sat Jan 7 23:24:50 2023 +1100 - - Skip dynamic-forward test on minix3. + Avoids turning on the obfucation when X11 forwarding only is in use, + which slows it right down. Reported by Roger Marsh - This test relies on loopback addresses which minix does not have. - Previously the test would not run at all since it also doesn't have - netcat, but now we use our own netcat it tries and fails. - -commit dd1249bd5c45128a908395c61b26996a70f82205 -Author: Damien Miller -Date: Sun Jan 8 12:08:59 2023 +1100 - - don't test IPv6 addresses if platform lacks support + OpenBSD-Commit-ID: c292f738db410f729190f92de100c39ec931a4f1 -commit d77fc611a62f2dfee0b654c31a50a814b13310dd -Author: dtucker@openbsd.org -Date: Fri Jan 6 12:33:33 2023 +0000 +commit 676377ce67807a24e08a54cd60ec832946cc6cae +Author: tobhe@openbsd.org +Date: Mon Nov 13 09:18:19 2023 +0000 - upstream: When OpenSSL is not available, skip parts of percent test + upstream: Make sure sftp_get_limits() only returns 0 if 'limits' - that require it. Based on github pr#368 from ren mingshuai. + was initialized. This fixes a potential uninitialized use of 'limits' in + sftp_init() if sftp_get_limits() returned early because of an unexpected + message type. - OpenBSD-Regress-ID: 49a375b2cf61ccb95b52e75e2e025cd10988ebb2 - -commit 1cd2aac312af9172f1b5cb06c2e1cd090abb83cf -Author: Darren Tucker -Date: Sat Jan 7 23:01:11 2023 +1100 - - Use our own netcat for dynamic-forward test. + ok djm@ - That way we can be surer about its behaviour rather than trying to - second-guess the behaviour of various netcat implementations. + OpenBSD-Commit-ID: 1c177d7c3becc1d71bc8763eecf61873a1d3884c -commit 26cab41c05d7b0859d2a1ea5b6ed253d91848a80 +commit 64e0600f23c6dec36c3875392ac95b8a9100c2d6 Author: Darren Tucker -Date: Sat Jan 7 14:30:43 2023 +1100 +Date: Mon Nov 13 20:03:31 2023 +1100 - Use autoconf to find openssl binary. + Test current releases of LibreSSL and OpenSSL. - It's possible to install an OpenSSL in a path not in the system's - default library search path. OpenSSH can still use this (eg if you - specify an rpath) but the openssl binary there may not work. If one is - available on the system path just use that. - -commit 5532e010a0eeb6aa264396514f9aed7948471538 -Author: Darren Tucker -Date: Sat Jan 7 10:34:18 2023 +1100 - - Check openssl_bin path is executable before using. - -commit 5d7b16cff48598d5908db970bfdc9ff9326142c8 -Author: Darren Tucker -Date: Fri Jan 6 23:19:07 2023 +1100 - - Set OPENSSL_BIN from OpenSSL directory. + Retire some of the older releases. -commit 344a0e8240eaf08da5d46a5e3a9ecad6e4f64c35 +commit c8ed7cc545879ac15f6ce428be4b29c35598bb2a Author: dtucker@openbsd.org -Date: Fri Jan 6 08:50:33 2023 +0000 +Date: Wed Nov 1 02:08:38 2023 +0000 - upstream: Save debug logs from ssh for debugging purposes. + upstream: Specify ssh binary to use - OpenBSD-Regress-ID: 109e40b06de1c006a3b8e0d8745b790b2c5870a0 - -commit e1ef172646f7f49c80807eea90225ef5e0be55a8 -Author: djm@openbsd.org -Date: Fri Jan 6 08:07:39 2023 +0000 - - upstream: regression test for ChannelTimeout + ... instead of relying on installed one. Fixes test failures in -portable + when running tests prior to installation. - OpenBSD-Regress-ID: 280bfbefcfa415428ad744e43f69a8dede8ad685 + OpenBSD-Regress-ID: b6d6ba71c23209c616efc805a60d9a445d53a685 -commit 2393ea8daf25853459eb07a528d7577688847777 -Author: djm@openbsd.org -Date: Fri Jan 6 07:18:18 2023 +0000 +commit e9fc2c48121cada1b4dcc5dadea5d447fe0093c3 +Author: Darren Tucker +Date: Wed Nov 1 13:11:31 2023 +1100 - upstream: fix typo in verbose logging + Put long-running test targets on hipri runners. - OpenBSD-Regress-ID: 0497cdb66e003b2f50ed77291a9104fba2e017e9 + Some of the selfhosted test targets take a long time to run for various + reasons, so label them for "libvirt-hipri" runners so that they can + start immediately. This should reduce the time to complete all tests. -commit 161a5378a3cc2e7aa3f9674cb7f4686ae6ce9586 +commit 7ddf27668f0e21233f08c0ab2fe9ee3fdd6ab1e2 Author: djm@openbsd.org -Date: Fri Jan 6 02:59:50 2023 +0000 - - upstream: unit tests for misc.c:ptimeout_* API - - OpenBSD-Regress-ID: 01f8fb12d08e5aaadd4bd4e71f456b6588be9a94 - -commit 018d671d78145f03d6f07ae9d64d51321da70325 -Author: tb@openbsd.org -Date: Wed Jan 4 22:48:57 2023 +0000 - - upstream: Copy bytes from the_banana[] rather than banana() - - Fixes test failure due to segfault seen on arm64 with xonly snap. - - ok djm - - OpenBSD-Regress-ID: 86e2aa4bbd1dff1bc4ebb2969c0d6474485be046 - -commit ab6bb69e251faa8b24f81b25c72ec0120f20cad4 -Author: Damien Miller -Date: Fri Jan 6 19:13:36 2023 +1100 +Date: Wed Nov 1 00:29:46 2023 +0000 - unbreak scp on NetBSD 4.x - - e555d5cad5 effectively increased the default copy buffer size for SFTP - transfers. This caused NetBSD 4.x to hang during the "copy local file to - remote file in place" scp.sh regression test. + upstream: add some tests of forced commands overriding Subsystem - This puts back the original 32KB copy buffer size until we can properly - figure out why. + directives - lots of debugging assistance from dtucker@ + OpenBSD-Regress-ID: eb48610282f6371672bdf2a8b5d2aa33cfbd322b -commit 2d1ff2b9431393ad99ef496d5e3b9dd0d4f5ac8c -Author: djm@openbsd.org -Date: Fri Jan 6 02:47:18 2023 +0000 +commit fb06f9b5a065dfbbef5916fc4accc03c0bf026dd +Author: dtucker@openbsd.org +Date: Tue Oct 31 04:15:40 2023 +0000 - upstream: Implement channel inactivity timeouts - - This adds a sshd_config ChannelTimeouts directive that allows channels that - have not seen traffic in a configurable interval to be automatically closed. - Different timeouts may be applied to session, X11, agent and TCP forwarding - channels. - - Note: this only affects channels over an opened SSH connection and not - the connection itself. Most clients close the connection when their channels - go away, with a notable exception being ssh(1) in multiplexing mode. + upstream: Don't try to use sudo inside sshd log wrapper. - ok markus dtucker + We still need to check if we're using sudo since we don't want to chown + unecessarily, as on some platforms this causes an error which pollutes + stderr. We also don't want to unnecessarily invoke sudo, since it's + running in the context of the proxycommand, on *other* platforms it + may not be able to authenticate, and if we're using SUDO then it should + already be privileged. - OpenBSD-Commit-ID: ae8bba3ed9d9f95ff2e2dc8dcadfa36b48e6c0b8 + OpenBSD-Regress-ID: 70d58df7503db699de579a9479300e5f3735f4ee -commit 0e34348d0bc0b1522f75d6212a53d6d1d1367980 -Author: djm@openbsd.org -Date: Fri Jan 6 02:42:34 2023 +0000 +commit fc3cc33e88c242c704781c6c48087838f1dcfa2a +Author: dtucker@openbsd.org +Date: Tue Oct 31 02:58:45 2023 +0000 - upstream: Add channel_set_xtype() - - This sets an "extended" channel type after channel creation (e.g. - "session:subsystem:sftp") that will be used for setting channel inactivity - timeouts. + upstream: Only try to chmod logfile if we have sudo. If we don't have - ok markus dtucker + sudo then we won't need to chmod. - OpenBSD-Commit-ID: 42564aa92345045b4a74300528f960416a15d4ca + OpenBSD-Regress-ID: dbad2f5ece839658ef8af3376cb1fb1cabe2e324 -commit ceedf09b2977f3a756c759a6e7eb8f8e9db86a18 +commit 3a506598fddd3f18f9095af3fe917f24cbdd32e0 Author: djm@openbsd.org -Date: Fri Jan 6 02:41:49 2023 +0000 +Date: Mon Oct 30 23:00:25 2023 +0000 - upstream: tweak channel ctype names - - These are now used by sshd_config:ChannelTimeouts to specify timeouts by - channel type, so force them all to use a similar format without whitespace. + upstream: move PKCS#11 setup code to test-exec.sh so it can be reused - ok dtucker markus + elsewhere - OpenBSD-Commit-ID: 66834765bb4ae14f96d2bb981ac98a7dae361b65 + OpenBSD-Regress-ID: 1d29e6be40f994419795d9e660a8d07f538f0acb -commit c60438158ad4b2f83d8504257aba1be7d0b0bb4b +commit f82fa227a52661c37404a6d33bbabf14fed05db0 Author: djm@openbsd.org -Date: Fri Jan 6 02:39:59 2023 +0000 +Date: Mon Oct 30 17:32:00 2023 +0000 - upstream: Add channel_force_close() - - This will forcibly close an open channel by simulating read/write errors, - draining the IO buffers and calling the detach function. - - Previously the detach function was only ever called during channel garbage - collection, but there was no way to signal the user of a channel (e.g. - session.c) that its channel was being closed deliberately (vs. by the - usual state-machine logic). So this adds an extra "force" argument to the - channel cleanup callback to indicate this condition. + upstream: tidy and refactor PKCS#11 setup code - ok markus dtucker + Replace the use of a perl script to delete the controlling TTY with a + SSH_ASKPASS script to directly load the PIN. - OpenBSD-Commit-ID: 23052707a42bdc62fda2508636e624afd466324b - -commit d478cdc7ad6edd4b1bcd1e86fb2f23194ff33d5a -Author: djm@openbsd.org -Date: Fri Jan 6 02:38:23 2023 +0000 - - upstream: replace manual poll/ppoll timeout math with ptimeout API + Move PKCS#11 setup code to functions in anticipation of it being used + elsewhere in additional tests. - feedback markus / ok markus dtucker + Reduce stdout spam - OpenBSD-Commit-ID: c5ec4f2d52684cdb788cd9cbc1bcf89464014be2 + OpenBSD-Regress-ID: 07705c31de30bab9601a95daf1ee6bef821dd262 -commit 4adf3817a24efe99b06e62630577d683c7cd8065 -Author: djm@openbsd.org -Date: Fri Jan 6 02:37:04 2023 +0000 +commit 3cf698c6d4ffa9be1da55672a3519e2135a6366a +Author: Darren Tucker +Date: Mon Oct 30 21:35:03 2023 +1100 - upstream: add ptimeout API for keeping track of poll/ppoll - - timeouts; ok dtucker markus - - OpenBSD-Commit-ID: 3335268ca135b3ec15a947547d7cfbb8ff929ead + Add obsd74 test VM and retire obsd69 and obsd70. -commit 8c7c69d32375d2f3ce9da0109c9bffc560842316 -Author: djm@openbsd.org -Date: Thu Jan 5 05:49:13 2023 +0000 +commit 3e21d58a09894acb38dc69ed615d101131f473d0 +Author: Darren Tucker +Date: Mon Oct 30 18:34:12 2023 +1100 - upstream: suppress "Connection closed" message when in quiet mode - - OpenBSD-Commit-ID: 8a3ab7176764da55f60bfacfeae9b82d84e3908f + Add OpenSSL 3.3.0 as a known dev version. -commit 845ceecea2ac311b0c267f9ecbd34862e1876fc6 -Author: djm@openbsd.org -Date: Mon Jan 2 07:03:57 2023 +0000 +commit 917ba181c2cbdb250a443589ec732aa36fd51ffa +Author: Darren Tucker +Date: Mon Oct 30 13:32:03 2023 +1100 - upstream: regression test for PermitRemoteOpen + Restore nopasswd sudo rule on Mac OS X. - OpenBSD-Regress-ID: 8271aafbf5c21950cd5bf966f08e585cebfe630c + This seems to be missing from some (but not all) github runners, so + restore it if it seems to be missing. -commit b3daa8dc582348d6ab8150bc1e571b7aa08c5388 -Author: djm@openbsd.org -Date: Mon Jan 2 07:03:30 2023 +0000 +commit c5698abad6d4ec98ca20bcaaabaeacd5e1ec3f4f +Author: Darren Tucker +Date: Mon Oct 30 13:26:52 2023 +1100 - upstream: fix bug in PermitRemoteOpen which caused it to ignore its - - first argument unless it was one of the special keywords "any" or "none". - - Reported by Georges Chaudy in bz3515; ok dtucker@ + Don't exit early when setting up on Mac OS X. - OpenBSD-Commit-ID: c5678a39f1ff79993d5ae3cfac5746a4ae148ea5 + We probably need some of the other bits in there (specifically, setting + the perms on the home directory) so make it less of a special snowflake. -commit 0872663a7be0301bcc3d49acdbc9b740a3d972d4 -Author: jmc@openbsd.org -Date: Mon Dec 26 19:16:03 2022 +0000 +commit 1d6a878ceba60b9dc14037dddc8f036070c0065f +Author: dtucker@openbsd.org +Date: Sun Oct 29 06:22:07 2023 +0000 - upstream: spelling fixes; from paul tagliamonte amendments to his + upstream: Only try to chown logfiles that exist to prevent spurious - diff are noted on tech + errors. - OpenBSD-Commit-ID: d776dd03d0b882ca9c83b84f6b384f6f9bd7de4a + OpenBSD-Regress-ID: f1b20a476734e885078c481f1324c9ea03af991e -commit 797da2812a71785b34890bb6eb44767a7d09cd34 -Author: djm@openbsd.org -Date: Fri Dec 16 07:13:22 2022 +0000 +commit e612376427a66f835e284f6b426d16d7c85301bc +Author: anton@openbsd.org +Date: Thu Oct 26 18:52:45 2023 +0000 - upstream: Mention that scp uses the SFTP protocol and remove + upstream: make use of bsd.regress.mk in extra and interop targets; ok - reference to legacy flag. Spotted by, feedback and ok jmc@ + dtucker@ - OpenBSD-Commit-ID: 9dfe04966f52e941966b46c7a2972147f95281b3 + OpenBSD-Regress-ID: 7ea21b5f6fc4506165093b2123d88d20ff13a4f0 -commit 93f2ce8c050a7a2a628646c00b40b9b53fef93ef -Author: djm@openbsd.org -Date: Fri Dec 16 06:56:47 2022 +0000 +commit ea0039173957d0edcd6469b9614dcedb44dcb4f9 +Author: dtucker@openbsd.org +Date: Thu Oct 26 12:44:07 2023 +0000 - upstream: Clear signal mask early in main(); sshd may have been - - started with one or more signals masked (sigprocmask(2) is not cleared - on fork/exec) and this could interfere with various things, e.g. the - login grace timer. - - Execution environments that fail to clear the signal mask before running - sshd are clearly broken, but apparently they do exist. - - Reported by Sreedhar Balasubramanian; ok dtucker@ + upstream: Skip conch interop tests when not enabled instead of fatal. - OpenBSD-Commit-ID: 77078c0b1c53c780269fc0c416f121d05e3010ae + OpenBSD-Regress-ID: b0abf81c24ac6c21f367233663228ba16fa96a46 -commit 4acfaabfae41badb9d334a2ee88c5c6ad041c0d5 -Author: jmc@openbsd.org -Date: Fri Dec 16 06:52:48 2022 +0000 +commit d220b9ed5494252b26b95f05be118472bc3ab5c0 +Author: dtucker@openbsd.org +Date: Wed Oct 25 05:38:08 2023 +0000 - upstream: add -X to usage(); + upstream: Import regenerated moduli. - OpenBSD-Commit-ID: 1bdc3df7de11d766587b0428318336dbffe4a9d0 + OpenBSD-Commit-ID: 95f5dd6107e8902b87dc5b005ef2b53f1ff378b8 -commit e555d5cad5afae7d5ef2bbc02ca591178fe16fed -Author: djm@openbsd.org -Date: Fri Dec 16 03:40:03 2022 +0000 +commit a611e4db4009447a0151f31a44e235ca32ed4429 +Author: anton@openbsd.org +Date: Wed Oct 25 08:01:59 2023 +0000 - upstream: add a -X option to both scp(1) and sftp(1) to allow - - control over some SFTP protocol knobs: the copy buffer length and - the number of inflight requests, both of which are used during - upload/download. - - Previously these could be controlled in sftp(1) using the -b/-R options. - This makes them available in both SFTP protocol clients using the same - option character sequence. + upstream: ssh conch interop tests requires a controlling terminal; ok dtucker@ - OpenBSD-Commit-ID: 27502bffc589776f5da1f31df8cb51abe9a15f1c + OpenBSD-Regress-ID: cbf2701bc347c2f19d907f113779c666f1ecae4a -commit 5a7a7acab2f466dc1d7467b5d05d35268c3137aa -Author: deraadt@openbsd.org -Date: Thu Dec 15 18:20:39 2022 +0000 +commit da951b5e08c167acb5d6e2eec6f146502f5d6ed8 +Author: anton@openbsd.org +Date: Mon Oct 23 11:30:49 2023 +0000 - upstream: The idiomatic way of coping with signed char vs unsigned + upstream: Use private key that is allowed by sshd defaults in conch - char (which did not come from stdio read functions) in the presence of - ctype macros, is to always cast to (unsigned char). casting to (int) - for a "macro" which is documented to take int, is weird. And sadly wrong, - because of the sing extension risk.. same diff from florian + interop tests. - OpenBSD-Commit-ID: 65b9a49a68e22ff3a0ebd593f363e9f22dd73fea - -commit b0b58222c7cc62efd8212c4fb65a545f58ebb22d -Author: Darren Tucker -Date: Mon Dec 19 18:49:51 2022 +1100 - - Simply handling of SSH_CONNECTION PAM env var. + ok dtucker@ - Prompted by bz#3508: there's no need to cache the value of - sshpam_conninfo so remove the global. While there, add check of - return value from pam_putenv. ok djm@ - -commit ed8444572ae684fdb892f97bae342c6cb6456f04 -Author: Darren Tucker -Date: Mon Dec 19 18:42:34 2022 +1100 - - Add tests for LibreSSL 3.7.0 and OpenSSL 1.1.1s. + OpenBSD-Regress-ID: 3b7f65c8f409c328bcd4b704f60cb3d31746f045 -commit abb9a8aaddfcacbd12641f6e4f203da0fa85a287 +commit 1ca166dbb3c0ce632b98869cd955f69320aa6fe8 Author: Darren Tucker -Date: Sun Dec 18 21:36:25 2022 +1100 +Date: Fri Oct 20 20:43:00 2023 +1100 - Use sudo when resetting perms on directories. + Install Dropbear for interop testing. -commit 2f5664c5908d84697cbe91302d5d5c4d83cb2121 +commit f993bb58351c5cb71e61aede63805a34a6d4daea Author: Darren Tucker -Date: Sun Dec 18 21:19:33 2022 +1100 +Date: Fri Oct 20 20:39:03 2023 +1100 - Set group perms on regress dir. + Resync PuTTY and Conch path handling with upstream. - This ensures that the tests don't fail due to StrictMode checks. - -commit 137196300fc1540affadde880210f02ba6cb4abf -Author: Darren Tucker -Date: Sun Dec 18 21:13:42 2022 +1100 - - Fetch regress logs from obj dir. + Now that configure finds these for us we can remove these -portable + specific changes. -commit 5f93c4836527d9fda05de8944a1c7b4a205080c7 +commit ff85becd5f5f06a76efa45d30fb204a3c5e5215c Author: Darren Tucker -Date: Tue Dec 13 20:59:54 2022 +1100 +Date: Fri Oct 20 20:35:46 2023 +1100 - obsdsnap test VMs runs-on libvirt too. + Have configure find PuTTY and Conch binaries. + + This will let us remove some -portable specific changes from + test-exec.sh. -commit 8386886fb1ab7fda73069fb0db1dbe0e5a52f758 -Author: Darren Tucker -Date: Tue Dec 13 20:55:37 2022 +1100 +commit c54a50359b9cecddbf3ffcdc26efcb3cd6071ec1 +Author: dtucker@openbsd.org +Date: Fri Oct 20 07:37:07 2023 +0000 - Run upstream obsdsnap tests on ephemeral runners. + upstream: Allow overriding the locations of the Dropbear binaries + + similar to what we do for the PuTTY ones. + + OpenBSD-Regress-ID: 7de0e00518fb0c8fdc5f243b7f82f523c936049c -commit b6e01459b55ece85d7f296b2bc719d1841e1009e -Author: Darren Tucker -Date: Tue Dec 13 20:48:56 2022 +1100 +commit fbaa707d455a61d0aef8ae65e02a25bac5351e5c +Author: dtucker@openbsd.org +Date: Fri Oct 20 06:56:45 2023 +0000 - Move obsdsnap test VMs to ephemeral runners. + upstream: Add interop test with Dropbear. + + Right now this is only dbclient not the Dropbear server since it won't + currently run as a ProxyCommand. + + OpenBSD-Regress-ID: 8cb898c414fcdb252ca6328896b0687acdaee496 -commit ea6fdf9a1aa71a411f7db218a986392c4fb55693 -Author: Damien Miller -Date: Fri Dec 9 18:00:21 2022 +1100 +commit c2003d0dbdcdb61ca336c3f90c5c2b4a09c8e73f +Author: Fabio Pedretti +Date: Mon Oct 16 11:59:53 2023 +0200 - use calloc for allocating arc4random structs + Update openssl-devel dependency in RPM spec. - ok dtucker + Since openssh 9.4p1, openssl >= 1.1.1 is required, so + build with --without-openssl elsewhere. + According to https://repology.org/project/openssl/versions + openssl 1.1.1 is available on fedora >= 29 and rhel >= 8. + Successfully build tested, installed and run on rhel 6 -commit 4403b62f5548e91389cb3339d26a9d0c4bb07b34 -Author: dtucker@openbsd.org -Date: Fri Dec 9 00:22:29 2022 +0000 +commit 064e09cd632721c7e6889904e07767443ee23821 +Author: Fabio Pedretti +Date: Mon Oct 16 10:13:06 2023 +0200 - upstream: Warn if no host keys for hostbased auth can be loaded. + Remove reference of dropped sshd.pam.old file - OpenBSD-Commit-ID: 2a0a13132000cf8d3593133c1b49768aa3c95977 + The file was removed in openssh 8.8 -commit a6183e25e3f1842e21999fe88bc40bb99b121dc3 +commit 62db354b696b378a164b6e478cb6b0171dcb0c3d Author: dtucker@openbsd.org -Date: Fri Dec 9 00:17:40 2022 +0000 +Date: Mon Oct 16 08:40:00 2023 +0000 - upstream: Add server debugging for hostbased auth. + upstream: Move declaration of "len" into the block where it's used. - auth_debug_add queues messages about the auth process which is sent to - the client after successful authentication. This also sends those to - the server debug log to aid in debugging. From bz#3507, ok djm@ + This lets us compile Portable with -Werror with when OpenSSL doesn't have + Ed25519 support. - OpenBSD-Commit-ID: 46ff67518cccf9caf47e06393e2a121ee5aa258a + OpenBSD-Commit-ID: e02e4b4af351946562a7caee905da60eff16ba29 -commit b85c3581c16aaf6e83b9a797c80705a56b1f312e -Author: cheloha@openbsd.org -Date: Sun Dec 4 23:50:49 2022 +0000 +commit 6eee8c972d5901d10e80634a006b4e346b2c8c19 +Author: Damien Miller +Date: Fri Oct 13 15:15:05 2023 +1100 - upstream: remove '?' from getopt(3) loops - - userspace: remove vestigial '?' cases from top-level getopt(3) loops - - getopt(3) returns '?' when it encounters a flag not present in the in - the optstring or if a flag is missing its option argument. We can - handle this case with the "default" failure case with no loss of - legibility. Hence, remove all the redundant "case '?':" lines. - - Prompted by dlg@. With help from dlg@ and millert@. - - Link: https://marc.info/?l=openbsd-tech&m=167011979726449&w=2 - - ok naddy@ millert@ dlg@ + run t-extra regress tests - OpenBSD-Commit-ID: b2f89346538ce4f5b33ab8011a23e0626a67e66e + This exposes the t-extra regress tests (including agent-pkcs11.sh) as + a new extra-tests target in the top level Makefile and runs them by + default. ok dtucker@ -commit 9a067e8d28a2249fd73f004961e30c113ee85e5d -Author: dtucker@openbsd.org -Date: Wed Dec 7 11:45:43 2022 +0000 +commit 637624dbbac13f2bc3c8ec5b15c9d627d07f2935 +Author: Darren Tucker +Date: Thu Oct 12 22:01:23 2023 +1100 - upstream: Fix comment typo. + Don't use make -j2. - OpenBSD-Regress-ID: 3b04faced6511bb5e74648c6a4ef4bf2c4decf03 + While we have 2 cores available on github runners, not using it means + that the most recent log message is the actual failure, rather than + having to search back through the log for it. -commit ce3c3e78ce45d68a82c7c8dc89895f297a67f225 +commit 971e0cfcfd52ef1d73cf5244074c306a60006e89 Author: Darren Tucker -Date: Wed Dec 7 18:58:25 2022 +1100 +Date: Thu Oct 12 16:23:05 2023 +1100 - Add SANDBOX_DEBUG to the kitchensink test build. + Correct arg order for ED255519 AC_LINK_IFELSE test. -commit bc234605fa3eb10f56bf0d74c8ecb0d91ada9d05 -Author: Damien Miller -Date: Wed Dec 7 18:38:25 2022 +1100 +commit c616e64688b2a0c1b4daad69b056099be998d121 +Author: djm@openbsd.org +Date: Thu Oct 12 03:51:08 2023 +0000 - disable SANDBOX_SECCOMP_FILTER_DEBUG - - It was mistakenly enabled in 2580916e4872 + upstream: typos and extra debug trace calls - Reported by Peter sec-openssh-com.22.fichtner AT 0sg.net + OpenBSD-Regress-ID: 98a2a6b9333743274359e3c0f0e65cf919a591d1 -commit b087c5cfa011b27992e01589314fec830266f99d -Author: Rose <83477269+AtariDreams@users.noreply.github.com> -Date: Tue Nov 29 15:12:54 2022 -0500 +commit c49a3fbf10162128c67c59562348de2041188974 +Author: djm@openbsd.org +Date: Thu Oct 12 03:48:53 2023 +0000 - Update autotools + upstream: ensure logs are owned by correct user; feedback/ok - Regenerate config files using latest autotools - -commit d63f5494978a185c7421d492b9c2f6f05bb54138 -Author: Darren Tucker -Date: Tue Dec 6 12:22:36 2022 +1100 - - Fix typo in comment. Spotted by tim@ + dtucker@ + + OpenBSD-Regress-ID: c3297af8f07717f1d400a5d34529962f1a76b5a3 -commit 73dcca12115aa12ed0d123b914d473c384e52651 -Author: dtucker@openbsd.org -Date: Sun Dec 4 11:03:11 2022 +0000 +commit 5ec0ed79ac074c3437b25f6cba8b8cf21c8d4587 +Author: djm@openbsd.org +Date: Thu Oct 12 03:36:32 2023 +0000 - upstream: Remove duplicate includes. + upstream: 64 %-expansion keys ought to be enough for anybody; ok - Patch from AtariDreams via github PR#364. + dtucker (we just hit the previous limit in some cases) - OpenBSD-Commit-ID: b9186638a05cb8b56ef7c0de521922b6723644ea + OpenBSD-Commit-ID: 84070f8001ec22ff5d669f836b62f206e08c5787 -commit 3cec15543010bc8d6997d896b1717a650afb7e92 +commit f59a94e22e46db2c23eddeb871aa9e8d93ab0016 Author: djm@openbsd.org -Date: Fri Dec 2 04:40:27 2022 +0000 +Date: Thu Oct 12 02:48:43 2023 +0000 - upstream: make struct sshbuf private + upstream: don't dereference NULL pointer when hashing jumphost - and remove an unused field; ok dtucker + OpenBSD-Commit-ID: 251c0263e1759a921341c7efe7f1d4c73e1c70f4 + +commit 281c79168edcc303abfd5bca983616eaa24c5f32 +Author: Damien Miller +Date: Thu Oct 12 13:20:01 2023 +1100 + + Solaris: prefer PRIV_XPOLICY to PRIV_LIMIT - OpenBSD-Commit-ID: c7a3d77c0b8c153d463398606a8d57569186a0c3 + If the system support PRIV_XPOLICY and one is set, then don't + modify PRIV_LIMIT. bz2833, patch from Ron Jordan, ok dtucker@ -commit 5796bf8ca9535f9fa7d01829a540d2550e05c860 -Author: Darren Tucker -Date: Fri Dec 2 11:43:36 2022 +1100 +commit 98fc34df837f3a3b79d2a111b96fe8a39adcab55 +Author: djm@openbsd.org +Date: Thu Oct 12 02:18:18 2023 +0000 - Restore ssh-agent permissions on exit. + upstream: add %j token that expands to the configured ProxyJump + + hostname (or the empty string if this option is not being used). bz3610, ok + dtucker - ...enough that subsequent builds can overwrite ssh-agent if necessary. + OpenBSD-Commit-ID: ce9983f7efe6a178db90dc5c1698df025df5e339 -commit ccf5a13868cbb4659107458cac1e017c98abcbda -Author: dtucker@openbsd.org -Date: Thu Dec 1 02:22:13 2022 +0000 +commit 7f3180be8a85320b5d3221714b40c16e66881249 +Author: djm@openbsd.org +Date: Thu Oct 12 02:15:53 2023 +0000 - upstream: Clean up ssh-add and ssh-agent logs. + upstream: release GSS OIDs only at end of authentication; bz2982, + + ok dtucker@ - OpenBSD-Regress-ID: 9eda8e4c3714d7f943ab2e73ed58a233bd29cd2c + OpenBSD-Commit-ID: 0daa41e0525ae63cae4483519ecaa37ac485d94c -commit 7a8b40cf6a5eda80173140cc6750a6db8412fa87 -Author: dtucker@openbsd.org -Date: Thu Dec 1 02:19:29 2022 +0000 +commit a612b93de5d86e955bfb6e24278f621118eea500 +Author: djm@openbsd.org +Date: Thu Oct 12 02:12:53 2023 +0000 - upstream: Log output of ssh-agent and ssh-add + upstream: mask SIGINT/TERM/QUIT/HUP before checking quit_pending - This should make debugging easier. + and use ppoll() to unmask them in the mainloop. Avoids race condition between + signaling ssh to exit and polling. bz3531; ok dtucker - OpenBSD-Regress-ID: 5974b02651f428d7e1079b41304c498ca7e306c8 + OpenBSD-Commit-ID: 5c14e1aabcddedb95cdf972283d9c0d5083229e7 -commit 4a1805d532616233dd6072e5cd273b96dd3062e6 -Author: dtucker@openbsd.org -Date: Tue Nov 29 22:41:14 2022 +0000 +commit 531b27a006116fe7aff325510aaa576f24844452 +Author: djm@openbsd.org +Date: Wed Oct 11 23:23:58 2023 +0000 - upstream: Add void to client_repledge args to fix compiler warning. ok djm@ + upstream: sync usage() with ssh.1; spotted by kn@ - OpenBSD-Commit-ID: 7e964a641ce4a0a0a11f047953b29929d7a4b866 + OpenBSD-Commit-ID: 191a85639477dcb5fa1616d270d93b7c8d5c1dfd -commit 815c4704930aa449edf6e812e99d69e9ffd31f01 +commit 64f7ca881b19be754425dca60d1590d306c9d1d0 Author: djm@openbsd.org -Date: Mon Nov 28 01:38:22 2022 +0000 +Date: Wed Oct 11 23:14:33 2023 +0000 - upstream: tighten pledge(2) after session establishment + upstream: ssh -Q does not make sense with other command-line options, - feedback, ok & testing in snaps deraadt@ + so give it its own line in the manpage - OpenBSD-Commit-ID: aecf4d49d28586dfbcc74328d9333398fef9eb58 + OpenBSD-Commit-ID: 00a747f0655c12122bbb77c2796be0013c105361 -commit f7cebbbf407d772ed71403d314343766782fe540 +commit a752a6c0e1001f93696d7025f0c867f0376e2ecf Author: djm@openbsd.org -Date: Mon Nov 28 01:37:36 2022 +0000 +Date: Wed Oct 11 22:42:26 2023 +0000 - upstream: New EnableEscapeCommandline ssh_config(5) option - - This option (default "no") controls whether the ~C escape is available. - Turning it off by default means we will soon be able to use a stricter - default pledge(2) in the client. + upstream: add ChannelTimeout support to the client, mirroring the - feedback deraadt@ dtucker@; tested in snaps for a while + same option in the server. ok markus@ - OpenBSD-Commit-ID: 7e277595d60acb8263118dcb66554472257b387a + OpenBSD-Commit-ID: 55630b26f390ac063980cfe7ad8c54b03284ef02 -commit d323f7ecf52e3d4ec1f4939bf31693e02f891dca -Author: mbuhl@openbsd.org -Date: Fri Nov 18 19:47:40 2022 +0000 +commit 76e91e7238cdc5662bc818e2a48d466283840d23 +Author: djm@openbsd.org +Date: Wed Oct 11 22:41:05 2023 +0000 - upstream: In channel_request_remote_forwarding the parameters for + upstream: add support for reading ED25519 private keys in PEM PKCS8 - permission_set_add are leaked as they are also duplicated in the call. Found - by CodeChecker. ok djm + format; ok markus@ tb@ - OpenBSD-Commit-ID: 4aef50fa9be7c0b138188814c8fe3dccc196f61e + OpenBSD-Commit-ID: 01b85c91757e6b057e9b23b8a23f96415c3c7174 -commit 62cc33e6eed847aafdc29e34aa69e9bd82a0ee16 -Author: Darren Tucker -Date: Wed Nov 30 11:23:11 2022 +1100 +commit fc77c8e352c0f44125425c05265e3a00c183d78a +Author: djm@openbsd.org +Date: Wed Oct 11 06:40:54 2023 +0000 - Use -fzero-call-used-regs=used on clang 15. - - clang 15 seems to have a problem with -fzero-call-used-reg=all which - causes spurious "incorrect signature" failures with ED25519. On those - versions, use -fzero-call-used-regs=used instead. (We may add exceptions - later if specific versions prove to be OK). Also move the GCC version - check to match. + upstream: mention "none" is a valid argument to IdentityFile; bz3080 - Initial investigation by Daniel Pouzzner (douzzer at mega nu), workaround - suggested by Bill Wendling (morbo at google com). bz#3475, ok djm@ - -commit f84b9cffd52c9c5c359a54a1929f9948e803ab1d -Author: Darren Tucker -Date: Mon Nov 28 21:09:28 2022 +1100 - - Skip unit tests on slow riscv64 hardware. + OpenBSD-Commit-ID: 1b4fb590ef731099349a7d468b77f02b240ac926 -commit 9f2747e0bed3faca92679eae69aef10c95dc82f5 -Author: Darren Tucker -Date: Sun Nov 27 15:26:22 2022 +1100 +commit c97520d23d1fe53d30725a2af25d2dddd6f2faff +Author: djm@openbsd.org +Date: Wed Oct 11 05:42:08 2023 +0000 - Rework how selfhosted tests interact with runners. - - Previously there was one runner per test target (mostly VMs). This had - a few limitations: - - multiple tests that ran on the same target (eg multiple build - configs) were serialized on availability or that runner. - - it needed manual balancing of VMs over host machines. + upstream: in olde rcp/scp protocol mode, when rejecting a path from the - To address this, make VMs that use ephemeral disks (ie most of them) - all use a pool of runners with the "libvirt" label. This requires that - we distinguish between "host" and "target" for those. Native runners - and VMs with persistent disks (eg the constantly-updated snapshot ones) - specify the same host and target. + server as not matching the glob that the client sent, log (at debug level) + the received pathname as well as the list of possible expected paths expanded + from the glob. bz2966 - This should improve test throughput. + OpenBSD-Commit-ID: 0bd8db8a595334ca86bca8f36e23fc0395315765 -commit d664ddaec87bdc7385be8ef7f1337793e1679d48 -Author: Darren Tucker -Date: Sun Nov 27 12:19:37 2022 +1100 +commit 208c2b719879805983398160791d6a1ef9c2c3fc +Author: djm@openbsd.org +Date: Wed Oct 11 04:46:29 2023 +0000 - Run vmstartup from temp dir. + upstream: s/%.100s/%s/ in SSH- banner construction as there's no - This will allow us to create ephemeral disk images per-runner. - -commit 0fa16e952b1fc1c4cf65e3dd138b0e87003e2e45 -Author: Darren Tucker -Date: Sun Nov 27 12:14:00 2022 +1100 - - Make "config" in matrix singular and pass in env. + reason to limit its size: the version string bring included is a compile time + constant going into an allocated banner string. - This will allow the startup scripts to adapt their behaviour based on - the type and config. - -commit e8857043af54809187be1e8b06749db61112899f -Author: Darren Tucker -Date: Sun Nov 27 11:42:22 2022 +1100 - - Add "libvirt" label to dfly30. + OpenBSD-Commit-ID: 0ef73304b9bf3e534c60900cd84ab699f859ebcd -commit 9775473d84902dc37753686cd10ae71fbe67efda -Author: Darren Tucker -Date: Sun Nov 27 09:28:20 2022 +1100 +commit 0354790826b97c41bbd171a965574e159b58d83e +Author: tb@openbsd.org +Date: Tue Oct 10 06:49:54 2023 +0000 - Rename "os" in matrix to "target". + upstream: Garbage collect cipher_get_keyiv_len() - This is in preparation to distinguish this from the host that the runner - runs on in case where they are separate (eg VMs). - -commit 04fd00ceff39f4544ced6f5342060abe584835d0 -Author: Darren Tucker -Date: Sun Nov 27 09:23:04 2022 +1100 - - Remove unused self-hosted test targets. - -commit c9d9fcad2a11c1cd1550a541f44091d65f0b5584 -Author: Darren Tucker -Date: Sun Nov 27 09:16:15 2022 +1100 - - Remove explicit "default" test config argument. + This is a compat20 leftover, unused since 2017. - Not specifying the test config implicitly selects default args. - -commit 15a01cf15f396f87c6d221c5a6af98331c818962 -Author: Darren Tucker -Date: Wed Nov 23 13:18:54 2022 +1100 - - Add fallback for old platforms w/out MAP_ANON. + ok djm + + OpenBSD-Commit-ID: 91fa5497c9dc6883064624ac27813a567883fdce -commit 6b9bbbfe8b26db6e9a30a7e08c223e85421aed98 -Author: Darren Tucker -Date: Wed Nov 23 13:09:11 2022 +1100 +commit 8d29ee4115001a02641386ae394992c65ed279e0 +Author: djm@openbsd.org +Date: Tue Oct 10 03:57:45 2023 +0000 - If we haven't found it yet, recheck for sys/stat.h. + upstream: Reserve a range of "local extension" message numbers that + + OpenSSH promises not to use (comment change only) - On some very old platforms, sys/stat.h needs sys/types.h, however - autoconf 2.71's AC_CHECK_INCLUDES_DEFAULT checks for them in the - opposite order, which in combination with modern autoconf's - "present but cannot be compiled" behaviour causes it to not be - detected. + OpenBSD-Commit-ID: e61795b453d4892d2c99ce1039112c4a00250e03 -commit 8926956f22639132a9f2433fcd25224e01b900f5 -Author: Darren Tucker -Date: Fri Nov 11 11:25:37 2022 +1100 +commit 90b0d73d63a706e85f6431f05a62d2ce1b476472 +Author: djm@openbsd.org +Date: Fri Oct 6 03:32:15 2023 +0000 - Add dfly62 test target. + upstream: typo in error message + + OpenBSD-Regress-ID: 6a8edf0dc39941298e3780b147b10c0a600b4fee -commit 650de7ecd3567b5a5dbf16dd1eb598bd8c20bca8 -Author: dtucker@openbsd.org -Date: Thu Nov 10 23:03:10 2022 +0000 +commit e84517f51532ec913d8fb01a8aab7307134774bb +Author: djm@openbsd.org +Date: Fri Oct 6 03:25:14 2023 +0000 - upstream: Handle dynamic remote port forwarding in escape commandline's + upstream: Perform the softhsm2 setup as discrete steps rather than - -R processing. bz#3499, ok djm@ + as a long shell pipeline. Makes it easier to figure out what has happened + when it breaks. - OpenBSD-Commit-ID: 194ee4cfe7ed0e2b8ad0727f493c798a50454208 + OpenBSD-Regress-ID: b3f1292115fed65765d0a95414df16e27772d81c -commit 5372db7e7985ba2c00f20fdff8942145ca99e033 -Author: Darren Tucker -Date: Thu Nov 10 12:44:51 2022 +1100 +commit cb54becff4d776238e0e9072943ba0872260535d +Author: claudio@openbsd.org +Date: Sun Sep 24 08:14:13 2023 +0000 - Remove seed passing over reexec. + upstream: REGRESS_FAIL_EARLY defaults to yes now. So no need to - This was added for the benefit of platforms using ssh-rand-helper to - prevent a delay on each connection as sshd reseeded itself. + overload the value here anymore. OK tb@ bluhm@ - ssh-random-helper is long gone, and since the re-exec happens before the - chroot the re-execed sshd can reseed itself normally. ok djm@ + OpenBSD-Regress-ID: f063330f1bebbcd373100afccebc91a965b14496 -commit ca98d3f8c64cfc51af81e1b01c36a919d5947ec2 -Author: Darren Tucker -Date: Wed Nov 9 20:59:20 2022 +1100 +commit f01f5137ceba65baf34ceac5a298c12ac01b1fef +Author: jmc@openbsd.org +Date: Wed Oct 4 05:42:10 2023 +0000 - Skip reexec test on OpenSSL 1.1.1 specifically. + upstream: spelling fix; - OpenSSL 1.1.1 has a bug in its RNG that breaks reexec fallback, so skip - that test. See bz#3483 for details. + OpenBSD-Commit-ID: 493f95121567e5ab0d9dd1150f873b5535ca0195 -commit 5ec4ebc2548e5f7f1b55b2a5cef5b67bdca8146f -Author: dtucker@openbsd.org -Date: Wed Nov 9 09:04:12 2022 +0000 +commit 80a2f64b8c1d27383cc83d182b73920d1e6a91f1 +Author: Damien Miller +Date: Wed Oct 4 15:34:10 2023 +1100 - upstream: Fix typo in fatal error message. - - Patch from vapier at chromium.org. - - OpenBSD-Commit-ID: 8a0c164a6a25eef0eedfc30df95bfa27644e35cf + crank version numbers -commit e6abafe9a6d809422d3432b95b3f9747b0acaa71 -Author: dtucker@openbsd.org -Date: Wed Nov 9 09:01:52 2022 +0000 +commit f65f187b105d9b5c12fd750a211397d08c17c6d4 +Author: djm@openbsd.org +Date: Wed Oct 4 04:04:09 2023 +0000 - upstream: Remove errant colon and simplify format - - string in error messages. Patch from vapier at chromium.org. + upstream: openssh-9.5 - OpenBSD-Commit-ID: fc28466ebc7b74e0072331947a89bdd239c160d3 + OpenBSD-Commit-ID: 5e0af680480bd3b6f5560cf840ad032d48fd6b16 -commit db2027a687516f87c3fb141e87154bb3d8a7807c +commit ffe27e54a4bb18d5d3bbd3f4cc93a41b8d94dfd2 Author: djm@openbsd.org -Date: Wed Nov 9 01:37:44 2022 +0000 +Date: Wed Oct 4 04:03:50 2023 +0000 - upstream: rename client_global_hostkeys_private_confirm() to + upstream: add some cautionary text about % token expansion and - client_global_hostkeys_prove_confirm(), as it handles the - "hostkeys-prove00@openssh.com" message; no functional change + shell metacharacters; based on report from vinci AT protonmail.ch - OpenBSD-Commit-ID: 31e09bd3cca6eed26855b88fb8beed18e9bd026d + OpenBSD-Commit-ID: aa1450a54fcee2f153ef70368d90edb1e7019113 -commit 1c2be7c2004cf1abcd172fee9fe3eab57cd4c426 +commit 60ec3d54fd1ebfe2dda75893fa1e870b8dffbb0d Author: djm@openbsd.org -Date: Wed Nov 9 00:15:59 2022 +0000 - - upstream: typo in comment - - OpenBSD-Commit-ID: 39c58f41e0f32d1ff31731fa6f5bbbc3ad25084a - -commit cf1a9852d7fc93e4abc4168aed09529a57427cdc -Author: Darren Tucker -Date: Wed Nov 9 09:23:47 2022 +1100 +Date: Tue Oct 3 23:56:10 2023 +0000 - Defer seed_rng until after closefrom call. + upstream: fix link to agent draft; spotted by Jann Horn - seed_rng will initialize OpenSSL, and some engine providers (eg Intel's - QAT) will open descriptors for their own use. bz#3483, patch from - joel.d.schuetze at intel.com, ok djm@ - -commit dffa64480163fbf76af7e4fb62c26bb0dd6642aa -Author: Darren Tucker -Date: Wed Nov 9 08:27:47 2022 +1100 - - Fix comment text. From emaste at freebsd.org. + OpenBSD-Commit-ID: ff5bda21a83ec013db683e282256a85201d2dc4b -commit d9df5689c29823ab830ec4f54c83c6cc3c0077ad -Author: Pierre Ossman -Date: Wed Jul 6 13:52:10 2022 +0200 +commit 12e2d4b13f6f63ce2de13cbfcc9e4d0d4b4ab231 +Author: Damien Miller +Date: Wed Oct 4 10:54:04 2023 +1100 - Avoid assuming layout of fd_set - - POSIX doesn't specify the internal layout of the fd_set object, so let's - not assume it is just a bit mask. This increases compatibility with - systems that have a different layout. + use portable provider allowlist path in manpage - The assumption is also worthless as we already refuse to use file - descriptors over FD_SETSIZE anyway. Meaning that the default size of - fd_set is quite sufficient. + spotted by Jann Horn -commit 419aa8a312e8d8f491933ca3d5933e602cb05aae -Author: Darren Tucker -Date: Tue Nov 8 12:42:52 2022 +1100 +commit 6c2c6ffde75df95fd838039850d3dd3d84956d87 +Author: deraadt@openbsd.org +Date: Tue Sep 19 20:37:07 2023 +0000 - Shutdown any VM before trying to check out repo. + upstream: typo; from Jim Spath - In the case where the previous run did not clean up, the checkout will - fail as it'll leave a stale mount. + OpenBSD-Commit-ID: 2f5fba917b5d4fcf93d9e0b0756c7f63189e228e -commit a32c07cbb78f65d8527642b96474a83b413f8108 -Author: Darren Tucker -Date: Tue Nov 8 11:33:25 2022 +1100 +commit b6b49130a0089b297245ee39e769231d7c763014 +Author: djm@openbsd.org +Date: Sun Sep 10 23:12:32 2023 +0000 - Run vm startup and shutdown from runner temp dir. + upstream: rename remote_glob() -> sftp_glob() to match other API - Should work even if the github workspace dir is on a stale sshfs mount. - -commit 2b40a7dfcdb8e616155b9504145aa52b271455aa -Author: Darren Tucker -Date: Tue Nov 8 11:03:31 2022 +1100 - - Add valrind-5 test here too. + OpenBSD-Commit-ID: d9dfb3708d824ec02970a84d96cf5937e0887229 -commit 2ea03d1f6d0a05ee2b63ed2dc0f2d54f1e4655a1 -Author: Darren Tucker -Date: Tue Nov 8 09:21:10 2022 +1100 +commit 21b79af6c8d2357c822c84cef3fbdb8001ed263b +Author: djm@openbsd.org +Date: Sun Sep 10 03:51:55 2023 +0000 - Update checkout and upload actions. + upstream: typo in comment - Update actions/checkout and actions/upload-artifact to main branch for - compatibility with node.js v16. + OpenBSD-Commit-ID: 69285e0ce962a7c6b0ab5f17a293c60a0a360a18 -commit 4e316ff0f18a118232bb9ac6512ee62773a9e8ea +commit 41232d25532b4d2ef6c5db62efc0cf50a79d26ca Author: Darren Tucker -Date: Tue Nov 8 09:17:04 2022 +1100 - - Split out rekey test since it runs the longest. - -commit 21625a6424258a92a96a3bb73ae6aabc5ed8a6b4 -Author: dtucker@openbsd.org -Date: Mon Nov 7 10:09:28 2022 +0000 +Date: Sun Sep 10 15:45:38 2023 +1000 - upstream: The IdentityFile option in ssh_config can also be used to - - specify a public key file, as documented in ssh.1 for the -i option. Document - this also for IdentityFile in ssh_config.5, for documentation completeness. - From laalsaas at systemli.org via portable github PR#352, ok jmc@ djm@ + Use zero-call-used-regs=used with Apple compilers. - OpenBSD-Commit-ID: 2f943be9f96e60ef81a9a4faa25b009999f9883b + Apple's versions of clang have version numbers that do not match the + corresponding upstream clang versions. Unfortunately, they do still + have the clang-15 zero-call-used-regs=all bug, so for now use the value + that doesn't result in segfaults. We could allowlist future versions + that are known to work. bz#3584 (and probably also our github CI + failures). -commit 747691604d3325ed2b62bad85b6fd8563ad32f6c -Author: dtucker@openbsd.org -Date: Mon Nov 7 10:05:38 2022 +0000 +commit 90ccc5918ea505bf156c31148b6b59a1bf5d6dc6 +Author: djm@openbsd.org +Date: Sun Sep 10 03:25:53 2023 +0000 - upstream: Remove some set but otherwise unused variables, spotted + upstream: randomise keystroke obfuscation intervals and average - in -portable by clang 16's -Wunused-but-set-variable. ok djm@ + interval rate. ok dtucker@ - OpenBSD-Commit-ID: 3d943ddf2369b38fbf89f5f19728e7dc1daf3982 + OpenBSD-Commit-ID: 05f61d051ab418fcfc4857ff306e420037502382 -commit 1d78d25653805aefc7a8dd9d86cd7359ada3823c -Author: dtucker@openbsd.org -Date: Mon Nov 7 10:02:59 2022 +0000 +commit bd1b9e52f5fa94d87223c90905c5fdc1a7c32aa6 +Author: djm@openbsd.org +Date: Fri Sep 8 06:34:24 2023 +0000 - upstream: Check for and disallow MaxStartups values less than or + upstream: fix sizeof(*ptr) instead sizeof(ptr) in realloc (pointer here - equal to zero during config parsing, rather than faling later at runtime. - bz#3489, ok djm@ + is char**, so harmless); spotted in CID 416964 - OpenBSD-Commit-ID: d79c2b7a8601eb9be493629a91245d761154308b + OpenBSD-Commit-ID: c61caa4a5a667ee20bb1042098861e6c72c69002 -commit a00f59a645072e5f5a8d207af15916a7b23e2642 +commit c4f966482983e18601eec70a1563115de836616f Author: djm@openbsd.org -Date: Mon Nov 7 04:04:40 2022 +0000 +Date: Fri Sep 8 06:10:57 2023 +0000 - upstream: fix parsing of hex cert expiry time; was checking whether the + upstream: regress test recursive remote-remote directories copies where - start time began with "0x", not the expiry time. + the directory contains a symlink to another directory. - from Ed Maste + also remove errant `set -x` that snuck in at some point - OpenBSD-Commit-ID: 6269242c3e1a130b47c92cfca4d661df15f05739 - -commit f58acaf8c7315483f4ac87d46a1aa2142a713cd8 -Author: Darren Tucker -Date: Mon Nov 7 15:10:59 2022 +1100 - - Fix merge conflict. - -commit 162e5741020a8d996c0c12b988b118e71ed728e6 -Author: Darren Tucker -Date: Mon Nov 7 15:04:33 2022 +1100 - - Branch-specific links for master status badges. - -commit e4b7c12ab24579312aa3ed38ce7041a439ec2d56 -Author: Darren Tucker -Date: Mon Nov 7 14:46:38 2022 +1100 - - Add CIFuzz status badge. + OpenBSD-Regress-ID: 1c94a48bdbd633ef2285954ee257725cd7bc456f -commit b496b9f831acd1e5bcd875e26e797488beef494a -Author: Darren Tucker -Date: Mon Nov 7 14:45:16 2022 +1100 +commit 5e1dfe5014ebc194641678303e22ab3bba15f4e5 +Author: djm@openbsd.org +Date: Fri Sep 8 06:10:02 2023 +0000 - Do not run CIFuzz on selfhosted tree. + upstream: fix recursive remote-remote copies of directories that - We already run it on the regular tree, no need to double up. - -commit 2138b1c4ddb300129a41a5104627b0d561184c7b -Author: Darren Tucker -Date: Mon Nov 7 14:41:58 2022 +1100 - - Whitespace change to trigger CIFuzz workflow. - -commit 4670b97ef87c7b0f21283c9b07c7191be88dda05 -Author: Darren Tucker -Date: Mon Nov 7 14:34:04 2022 +1100 - - Run cifuzz workflow on the actions as regular CI. - -commit 79391e66ce851ace1baf3c6a35e83a23f08ec2ba -Author: David Korczynski -Date: Tue Nov 30 11:45:20 2021 +0000 - - Add CIFuzz integration - -commit c1893364a0be243270014d7d34362a8101d55112 -Author: dtucker@openbsd.org -Date: Mon Nov 7 02:21:22 2022 +0000 - - upstream: Import regenerated moduli. + contain symlinks to other directories (similar to bz3611) - OpenBSD-Commit-ID: b0e54ee4d703bd6929bbc624068666a7a42ecb1f + OpenBSD-Commit-ID: 7e19d2ae09b4f941bf8eecc3955c9120171da37f -commit 5c3f18fb994ef27e685b205ee2351851b80fdbd1 -Author: dtucker@openbsd.org -Date: Mon Nov 7 01:53:01 2022 +0000 +commit 7c0ce2bf98b303b6ad91493ee3247d96c18ba1f6 +Author: djm@openbsd.org +Date: Fri Sep 8 05:50:57 2023 +0000 - upstream: Fix typo. From pablomh via -portable github PR#344. + upstream: regress test for recursive copies of directories containing - OpenBSD-Commit-ID: d056ee2e73691dc3ecdb44a6de68e6b88cd93827 - -commit e1c6fcc142066417c9832e634463faa3dd5d116c -Author: Darren Tucker -Date: Mon Nov 7 12:46:58 2022 +1100 - - Link to branch-specific queries for V_9_1 status. - -commit 4f4a5fad6d8892c3f8ee9cd81ec7de6458210c9f -Author: Darren Tucker -Date: Sun Nov 6 10:55:59 2022 +1100 - - Use "prohibit-password" in -portable comments. + symlinks to other directories. bz3611, ok dtucker@ - "without-password" is the deprecated alias for "prohibit-password", - so we should reference the latter. From emaste at freebsd.org. + OpenBSD-Regress-ID: eaa4c29cc5cddff4e72a16bcce14aeb1ecfc94b9 -commit 0f7e1eba55259ec037f515000b4c4afbf446230a -Author: Darren Tucker -Date: Sun Nov 6 10:50:01 2022 +1100 +commit 2de990142a83bf60ef694378b8598706bc654b08 +Author: djm@openbsd.org +Date: Fri Sep 8 05:56:13 2023 +0000 - Fix tracing disable on FreeBSD. + upstream: the sftp code was one of my first contributions to - Some versions of FreeBSD do not support using id 0 to refer to the - current pid for procctl, so pass getpid() explicitly. From - emaste at freebsd.org. - -commit 32fddb982fd61b11a2f218a115975a87ab126d43 -Author: Darren Tucker -Date: Mon Nov 7 10:39:01 2022 +1100 - - Fix setres*id checks to work with clang-16. + OpenSSH and it shows - the function names are terrible. - glibc has the prototypes for setresuid and setresgid behind _GNU_SOURCE, - and clang 16 will error out on implicit function definitions, so add - _GNU_SOURCE and the required headers to the configure checks. From - sam at @gentoo.org via bz#3497. - -commit 12af712d116f42164bcfa56db901d06e4fa27199 -Author: Sam James -Date: Sun Nov 6 04:52:38 2022 +0000 - - configure.ac: Fix -Wstrict-prototypes + Rename do_blah() to sftp_blah() to make them less so. - Clang 16 now warns on this and it'll be removed in C23, so let's - just be future proof. It also reduces noise when doing general - Clang 16 porting work (which is a big job as it is). github PR#355. + Completely mechanical except for sftp_stat() and sftp_lstat() which + change from returning a pointer to a static variable (error-prone) to + taking a pointer to a caller-provided receiver. - Signed-off-by: Sam James + OpenBSD-Commit-ID: eb54d6a72d0bbba4d623e2175cf5cc4c75dc2ba4 -commit 40b0a5eb6e3edfa2886b60c09c7803353b0cc7f5 -Author: Sam James -Date: Sun Nov 6 04:47:35 2022 +0000 +commit 249d8bd0472b53e3a2a0e138b4c030a31e83346a +Author: djm@openbsd.org +Date: Fri Sep 8 05:50:12 2023 +0000 - configure.ac: Add include for openpty + upstream: fix scp in SFTP mode recursive upload and download of - Another Clang 16ish fix (which makes -Wimplicit-function-declaration - an error by default). github PR#355. + directories that contain symlinks to other directories. In scp mode, the + links would be followed, but in SFTP mode they were not. bz3611, ok dtucker@ - See: 2efd71da49b9cfeab7987058cf5919e473ff466b - See: be197635329feb839865fdc738e34e24afd1fca8 - -commit 6b17e128879ec6cc32ca2c28b5d894b4aa72e32d -Author: Rochdi Nassah -Date: Fri Oct 28 01:26:31 2022 +0100 - - Fix broken zlib link. + OpenBSD-Commit-ID: 9760fda668eaa94a992250d7670dfbc62a45197c -commit 99500df246ccb736ddbdd04160dcc82165d81a77 -Author: Darren Tucker -Date: Fri Nov 4 16:59:26 2022 +1100 +commit 0e1f4401c466fa4fdaea81b6dadc8dd1fc4cf0af +Author: djm@openbsd.org +Date: Wed Sep 6 23:36:09 2023 +0000 - Don't run openbsd-compat tests on Cygwin. + upstream: regression test for override of subsystem in match blocks - Add "compat-tests" to the default TEST_TARGET so we can override as - necessary. Override TEST_TARGET for Cygwin as the tests don't currently - compile there. + OpenBSD-Regress-ID: 5f8135da3bfda71067084c048d717b0e8793e87c -commit 3cae9f92a31897409666aa1e6f696f779759332b +commit 8a1450c62035e834d8a79a5d0d1c904236f9dcfe Author: djm@openbsd.org -Date: Thu Nov 3 21:59:20 2022 +0000 +Date: Wed Sep 6 23:35:35 2023 +0000 - upstream: replace recently-added valid_domain() check for hostnames + upstream: allow override of Sybsystem directives in sshd Match - going to known_hosts with a more relaxed check for bad characters; previous - commit broke address literals. Reported by/feedback from florian@ + blocks - OpenBSD-Commit-ID: 10b86dc6a4b206adaa0c11b58b6d5933898d43e0 - -commit 9655217231c9056200bea7ae2dffcc9c0c3eb265 -Author: Darren Tucker -Date: Thu Nov 3 23:07:50 2022 +1100 - - Rerun tests on changes to Makefile.in in any dir. + OpenBSD-Commit-ID: 3911d18a826a2d2fe7e4519075cf3e57af439722 -commit 3500f0405a3ab16b59a26f3508c4257a3fc3bce6 -Author: Darren Tucker -Date: Thu Nov 3 23:04:08 2022 +1100 +commit 6e52826e2a74d077147a82ead8d4fbd5b54f4e3b +Author: djm@openbsd.org +Date: Wed Sep 6 23:26:37 2023 +0000 - Link libssh into compat tests. + upstream: allocate the subsystems array as necessary and remove the - The cygwin compat code uses xmalloc, so add libssh.a so pick up that. - -commit ec59effcf65b8a4c85d47ff5a271123259dd0ab8 -Author: Darren Tucker -Date: Thu Nov 3 21:44:23 2022 +1100 - - Fix compat regress to work with non-GNU make. - -commit 73550a218e7dfbbd599534cbf856309bc924f6fd -Author: Darren Tucker -Date: Thu Nov 3 13:41:16 2022 +1100 - - Increase selfhosted job timeout. + fixed limit of subsystems. Saves a few kb of memory in the server and makes + it more like the other options. - The default job timeout of 360 (6h) is not enough to complete the - regress tests for some of the slow VMs depending on the load on the host. - Increase to 600 (10h). - -commit db97d8d0b90c6ce52b94b153d6f8f5f7d3b11777 -Author: Darren Tucker -Date: Thu Nov 3 10:00:43 2022 +1100 - - Only run opensslver tests if built with OpenSSL. - -commit ba053709638dff2f6603df0c1f340352261d63ea -Author: Darren Tucker -Date: Wed Nov 2 14:16:04 2022 +1100 - - Add tests for OpenSSL 3.0.7 and LibreSSL 3.6.1. - -commit edd24101c7e17d1a8f6576e1aaf62233b47ad6f5 -Author: Darren Tucker -Date: Thu Nov 3 08:17:39 2022 +1100 - - Run compat regress tests too. + OpenBSD-Commit-ID: e683dfca6bdcbc3cc339bb6c6517c0c4736a547f -commit fe88d67e7599b0bc73f6e4524add28d743e7f977 -Author: Darren Tucker -Date: Thu Nov 3 08:14:05 2022 +1100 +commit e19069c9fac4c111d6496b19c7f7db43b4f07b4f +Author: djm@openbsd.org +Date: Wed Sep 6 23:23:53 2023 +0000 - Compat tests need libcrypto. + upstream: preserve quoting of Subsystem commands and arguments. - This was moved to CHANNELLIBS during the libs refactor. Spotted by - rapier at psc.edu. - -commit 96b519726b7944eee3c23a54eee3d5c031ba1533 -Author: Darren Tucker -Date: Thu Nov 3 04:24:39 2022 +1100 - - Include time.h when defining timegm. + This may change behaviour of exotic configurations, but the most common + subsystem configuration (sftp-server) is unlikely to be affected. - Fixes build on some platforms eg recent AIX. + OpenBSD-Commit-ID: 8ffa296aeca981de5b0945242ce75aa6dee479bf -commit da6038bd5cd55eb212eb2aec1fc8ae79bbf76156 -Author: Darren Tucker -Date: Tue Nov 1 19:10:30 2022 +1100 +commit 52dfe3c72d98503d8b7c6f64fc7e19d685636c0b +Author: djm@openbsd.org +Date: Wed Sep 6 23:21:36 2023 +0000 - Always use compat getentropy. + upstream: downgrade duplicate Subsystem directives from being a - Have it call native getentropy and fall back as required. Should fix - issues of platforms where libc has getentropy but it is not implemented - in the kernel. Based on github PR#354 from simsergey. - -commit 5ebe18cab6be3247b44c807ac145164010465b82 -Author: Darren Tucker -Date: Wed Nov 2 10:51:48 2022 +1100 - - Check for sockaddr_in.sin_len. + fatal error to being a debug message to match behaviour with just about all + other directives. - If found, set SOCK_HAS_LEN which is used in addr.c. Should fix keyscan - tests on platforms with this (eg old NetBSD). + OpenBSD-Commit-ID: fc90ed2cc0c18d4eb8e33d2c5e98d25f282588ce -commit a1febadf426536612c2734168d409147c392e7cf -Author: dtucker@openbsd.org -Date: Sun Oct 30 18:42:07 2022 +0000 +commit 1ee0a16e07b6f0847ff463d7b5221c4bf1876e25 +Author: djm@openbsd.org +Date: Wed Sep 6 23:18:15 2023 +0000 - upstream: Use variable for diff options + upstream: handle cr+lf (instead of just cr) in sshsig signature - instead of unconditionally specifying "-rN". This will make life easier - in -portable where not all diff's understand -N. + files - OpenBSD-Regress-ID: 8b8a407115546be1c6d72d350b1e4f1f960d3cd3 + OpenBSD-Commit-ID: 647460a212b916540016d066568816507375fd7f -commit f6d3ed9a8a9280cbb68d6a499850cfe810e92bd0 -Author: Darren Tucker -Date: Mon Oct 31 05:13:02 2022 +1100 +commit e1c284d60a928bcdd60bc575c6f9604663502770 +Author: job@openbsd.org +Date: Mon Sep 4 10:29:58 2023 +0000 - OpenSSL dev branch is 302 not 320. + upstream: Generate Ed25519 keys when invoked without arguments - While there, also accept 301 which it shat it was previously. - -commit 25c8a2bbcc10c493d27faea57c42a6bf13fa51f2 -Author: djm@openbsd.org -Date: Fri Oct 28 02:47:04 2022 +0000 - - upstream: put sshkey_check_rsa_length() back in sshkey.c to unbreak + Ed25519 public keys are very convenient due to their small size. + OpenSSH has supported Ed25519 since version 6.5 (January 2014). - OPENSSL=no builds + OK djm@ markus@ sthen@ deraadt@ - OpenBSD-Commit-ID: 99eec58abe382ecd14b14043b195ee1babb9cf6e + OpenBSD-Commit-ID: f498beaad19c8cdcc357381a60df4a9c69858b3f -commit 1192588546c29ceec10775125f396555ea71850f +commit 694150ad92765574ff82a18f4e86322bd3231e68 Author: djm@openbsd.org -Date: Fri Oct 28 02:29:34 2022 +0000 +Date: Mon Sep 4 00:08:14 2023 +0000 - upstream: allow ssh-keyscan(1) to accept CIDR address ranges, e.g. - - ssh-keyscan 192.168.0.0/24 + upstream: trigger keystroke timing obfucation only if the channels - If a CIDR range is passed, then it will be expanded to all possible - addresses in the range including the all-0s and all-1s addresses. + layer enqueud some data in the last poll() cycle; this avoids triggering the + obfuscatior for non-channels data like ClientAlive probes and also fixes a + related problem were the obfucations would be triggered on fully quiescent + connections. - bz#976 feedback/ok markus@ + Based on / tested by naddy@ - OpenBSD-Commit-ID: ce6c5211f936ac0053fd4a2ddb415277931e6c4b - -commit 64af4209309461c79c39eda2d13f9d77816c6398 -Author: Damien Miller -Date: Fri Oct 28 12:54:35 2022 +1100 - - fix merge botch + OpenBSD-Commit-ID: d98f32dc62d7663ff4660e4556e184032a0db123 -commit 27267642699342412964aa785b98afd69d952c88 +commit b5fd97896b59a3a46245cf438cc8b16c795d9f74 Author: djm@openbsd.org -Date: Fri Oct 28 00:44:44 2022 +0000 +Date: Mon Sep 4 00:04:02 2023 +0000 - upstream: refactor sshkey_private_deserialize + upstream: avoid bogus "obfuscate_keystroke_timing: stopping ..." - feedback/ok markus@ + debug messages when keystroke timing obfuscation was never started; spotted + by naddy@ - OpenBSD-Commit-ID: f5ca6932fdaf840a5e8250becb38315a29b5fc9f + OpenBSD-Commit-ID: 5c270d35f7d2974db5c1646e9c64188f9393be31 -commit 2519a7077a9332f70935e5242ba91ee670ed6b87 +commit ccf7d913db34e49b7a6db1b8331bd402004c840d Author: djm@openbsd.org -Date: Fri Oct 28 00:44:17 2022 +0000 +Date: Mon Sep 4 00:01:46 2023 +0000 - upstream: refactor sshkey_private_serialize_opt() + upstream: make channel_output_poll() return a flag indicating - feedback/ok markus@ + whether channel data was enqueued. Will be used to improve keystroke timing + obfuscation. Problem spotted by / tested by naddy@ - OpenBSD-Commit-ID: 61e0fe989897901294efe7c3b6d670cefaf44cbd + OpenBSD-Commit-ID: f9776c7b0065ba7c3bbe50431fd3b629f44314d0 -commit 11a768adf98371fe4e43f3b06014024c033385d5 +commit 43254b326ac6e2131dbd750f9464dc62c14bd5a7 Author: djm@openbsd.org -Date: Fri Oct 28 00:43:30 2022 +0000 +Date: Sun Sep 3 23:59:32 2023 +0000 - upstream: refactor certify + upstream: set interactive mode for ControlPersist sessions if they - feedback/ok markus@ + originally requested a tty; enables keystroke timing obfuscation for most + ControlPersist sessions. Spotted by naddy@ - OpenBSD-Commit-ID: 35d742992e223eaca3537e6fb3d3002c08eed4f6 + OpenBSD-Commit-ID: 72783a26254202e2f3f41a2818a19956fe49a772 -commit 3fbc58bb249d967cc43ebdc554f6781bb73d4a58 -Author: djm@openbsd.org -Date: Fri Oct 28 00:43:08 2022 +0000 +commit ff3eda68ceb2e2bb8f48e3faceb96076c3e85c20 +Author: Darren Tucker +Date: Thu Aug 31 23:02:35 2023 +1000 - upstream: refactor sshkey_sign() and sshkey_verify() - - feedback/ok markus@ + Set LLONG_MAX for C89 test. - OpenBSD-Commit-ID: 368e662c128c99d05cc043b1308d2b6c71a4d3cc + If we don't have LLONG_MAX, configure will figure out that it can get it + by setting -std=gnu99, at which point we won't be testing C89 any more. + To avoid this, feed it in via CFLAGS. -commit a1deb6cdbbe6afaab74ecb08fcb62db5739267be +commit f98031773db361424d59e3301aa92aacf423d920 Author: djm@openbsd.org -Date: Fri Oct 28 00:41:52 2022 +0000 +Date: Tue Aug 29 02:50:10 2023 +0000 - upstream: refactor sshkey_from_blob_internal() - - feedback/ok markus@ + upstream: make PerSourceMaxStartups first-match-wins; ok dtucker@ - OpenBSD-Commit-ID: 1f46c0cbb8060ee9666a02749594ad6658c8e283 + OpenBSD-Commit-ID: dac0c24cb709e3c595b8b4f422a0355dc5a3b4e7 -commit 7d00799c935271ce89300494c5677190779f6453 +commit cfa66857db90cd908de131e0041a50ffc17c7df8 Author: djm@openbsd.org -Date: Fri Oct 28 00:41:17 2022 +0000 +Date: Mon Aug 28 09:52:09 2023 +0000 - upstream: refactor sshkey_from_private() - - feedback/ok markus@ + upstream: descriptive text shouldn't be under .Cm - OpenBSD-Commit-ID: e5dbe7a3545930c50f70ee75c867a1e08b382b53 + OpenBSD-Commit-ID: b1afaeb456a52bc8a58f4f9f8b2f9fa8f6bf651b -commit 262647c2e920492ca57f1b9320d74f4a0f6e482b +commit 01dbf3d46651b7d6ddf5e45d233839bbfffaeaec Author: djm@openbsd.org -Date: Fri Oct 28 00:39:29 2022 +0000 +Date: Mon Aug 28 09:48:11 2023 +0000 - upstream: factor out key generation + upstream: limit artificial login delay to a reasonable maximum (5s) - feedback/ok markus@ + and don't delay at all for the "none" authentication mechanism. Patch by + Dmitry Belyavskiy in bz3602 with polish/ok dtucker@ - OpenBSD-Commit-ID: 5b4211bff4de8d9adb84bc72857a8c42c44e7ceb + OpenBSD-Commit-ID: 85b364676dd84cf1de0e98fc2fbdcb1a844ce515 -commit 401c74e7dc15eab60540653d2f94d9306a927bab -Author: djm@openbsd.org -Date: Fri Oct 28 00:38:58 2022 +0000 +commit 528da5b9d7c5da01ed7a73ff21c722e1b5326006 +Author: jmc@openbsd.org +Date: Mon Aug 28 05:32:28 2023 +0000 - upstream: refactor and simplify sshkey_read() - - feedback/ok markus@ + upstream: add spacing for punctuation when macro args; - OpenBSD-Commit-ID: 0d93b7a56e31cd06a8bb0d2191d084ce254b0971 + OpenBSD-Commit-ID: e80343c16ce0420b2aec98701527cf90371bd0db -commit 591fed94e66a016acf87f4b7cd416ce812f2abe8 +commit 3867361ca691d0956ef7d5fb8181cf554a91d84a Author: djm@openbsd.org -Date: Fri Oct 28 00:37:24 2022 +0000 +Date: Mon Aug 28 04:06:52 2023 +0000 - upstream: factor out public key serialization + upstream: explicit long long type in timing calculations (doesn't - feedback/ok markus@ + matter, since the range is pre-clamped) - OpenBSD-Commit-ID: a3570c4b97290c5662890aea7328d87f55939033 + OpenBSD-Commit-ID: f786ed902d04a5b8ecc581d068fea1a79aa772de -commit 1e78844ae2b2dc01ba735d5ae740904c57e13685 +commit 7603ba71264e7fa938325c37eca993e2fa61272f Author: djm@openbsd.org -Date: Fri Oct 28 00:36:31 2022 +0000 +Date: Mon Aug 28 03:31:16 2023 +0000 - upstream: factor out sshkey_equal_public() + upstream: Add keystroke timing obfuscation to the client. + + This attempts to hide inter-keystroke timings by sending interactive + traffic at fixed intervals (default: every 20ms) when there is only a + small amount of data being sent. It also sends fake "chaff" keystrokes + for a random interval after the last real keystroke. These are + controlled by a new ssh_config ObscureKeystrokeTiming keyword/ feedback/ok markus@ - OpenBSD-Commit-ID: 1368ba114cb37732fe6ec3d89c7e6d27ea6fdc94 + OpenBSD-Commit-ID: 02231ddd4f442212820976068c34a36e3c1b15be -commit 25de1c01a8b9a2c8ab9b1da22444a03e89c982de +commit dce6d80d2ed3cad2c516082682d5f6ca877ef714 Author: djm@openbsd.org -Date: Fri Oct 28 00:35:40 2022 +0000 +Date: Mon Aug 28 03:28:43 2023 +0000 - upstream: begin big refactor of sshkey + upstream: Introduce a transport-level ping facility - Move keytype data and some of the type-specific code (allocation, - cleanup, etc) out into each key type's implementation. Subsequent - commits will move more, with the goal of having each key-*.c file - owning as much of its keytype's implementation as possible. + This adds a pair of SSH transport protocol messages SSH2_MSG_PING/PONG + to implement a ping capability. These messages use numbers in the "local + extensions" number space and are advertised using a "ping@openssh.com" + ext-info message with a string version number of "0". - lots of feedback + ok markus@ + ok markus@ - OpenBSD-Commit-ID: 0f2b4334f73914344e9e5b3d33522d41762a57ec + OpenBSD-Commit-ID: b6b3c4cb2084c62f85a8dc67cf74954015eb547f -commit 445363433ba20b8a3e655b113858c836da46a1cb -Author: djm@openbsd.org -Date: Mon Oct 24 22:43:36 2022 +0000 +commit d2d247938b38b928f8a6e1a47a330c5584d3a358 +Author: tobhe@openbsd.org +Date: Mon Aug 21 21:16:18 2023 +0000 - upstream: Be more paranoid with host/domain names coming from the + upstream: Log errors in kex_exchange_identification() with level - never write a name with bad characters to a known_hosts file. + verbose instead of error to reduce preauth log spam. All of those get logged + with a more generic error message by sshpkt_fatal(). - reported by David Leadbeater, ok deraadt@ + feedback from sthen@ + ok djm@ - OpenBSD-Commit-ID: ba9b25fa8b5490b49398471e0c9657b0cbc7a5ad + OpenBSD-Commit-ID: bd47dab4695b134a44c379f0e9a39eed33047809 -commit 7190154de2c9fe135f0cc1ad349cb2fa45152b89 +commit 9d7193a8359639801193ad661a59d1ae4dc3d302 Author: djm@openbsd.org -Date: Mon Oct 24 21:52:50 2022 +0000 +Date: Mon Aug 21 04:59:54 2023 +0000 - upstream: regress test for unmatched glob characters; fails before + upstream: correct math for ClientAliveInterval that caused the - previous commit but passes now. bz3488; prodded by dtucker@ + probes to be sent less frequently than configured; from Dawid Majchrzak - OpenBSD-Regress-ID: 0cc5cc9ea4a6fd170dc61b9212f15badaafb3bbd + OpenBSD-Commit-ID: 641153e7c05117436ddfc58267aa267ca8b80038 -commit a4821a592456c3add3cd325db433110cdaaa3e5c -Author: djm@openbsd.org -Date: Mon Oct 24 21:51:55 2022 +0000 +commit 3c6ab63b383b0b7630da175941e01de9db32a256 +Author: Darren Tucker +Date: Fri Aug 25 14:48:02 2023 +1000 - upstream: when scp(1) is using the SFTP protocol for transport (the - - default), better match scp/rcp's handling of globs that don't match the - globbed characters but do match literally (e.g. trying to transfer - "foo.[1]"). - - Previously scp(1) in SFTP mode would not match these pathnames but - legacy scp/rcp mode would. - - Reported by Michael Yagliyan in bz3488; ok dtucker@ + Include Portable version in sshd version string. - OpenBSD-Commit-ID: d8a3773f53015ba811fddba7473769a2fd343e11 + bz#3608, ok djm@ -commit 18376847b8043ba967eabbe23692ef74c9a3fddc -Author: jsg@openbsd.org -Date: Thu Oct 13 09:09:28 2022 +0000 +commit 17fa6cd10a26e193bb6f65d21264d2fe553bcd87 +Author: Darren Tucker +Date: Mon Aug 21 19:47:58 2023 +1000 - upstream: use correct type with sizeof ok djm@ + obsd-arm64 host is real hardware... - OpenBSD-Commit-ID: d6c882c2e8a42ff831a5b3cbc2c961ecb2dd6143 + so put in the correct config location. -commit 4a4883664d6b4e9e4e459a8cdc16bd8d4b735de9 -Author: jmc@openbsd.org -Date: Fri Oct 7 06:00:58 2022 +0000 +commit 598ca75c85acaaacee5ef954251e489cc20d7be9 +Author: Darren Tucker +Date: Mon Aug 21 18:38:36 2023 +1000 - upstream: ssh-agent.1: - use Nm not Xr for self-ref - while here, - - wrap a long line - - ssh-agent.c: - - add -O to usage() - - OpenBSD-Commit-ID: 855dac4695cef22e96d69c53436496bc408ca389 + Add OpenBSD ARM64 test host. + +commit 1acac79bfbe207e8db639e8043524962037c8feb +Author: Darren Tucker +Date: Mon Aug 21 18:05:26 2023 +1000 + + Add test for zlib development branch. -commit 9fd2441113fce2a83fc7470968c3b27809cc7f10 +commit 84efebf352fc700e9040c8065707c63caedd36a3 Author: djm@openbsd.org -Date: Fri Oct 7 04:06:26 2022 +0000 +Date: Mon Aug 21 04:36:46 2023 +0000 - upstream: document "-O no-restrict-websafe"; spotted by Ross L - - Richardson + upstream: want stdlib.h for free(3) - OpenBSD-Commit-ID: fe9eaa50237693a14ebe5b5614bf32a02145fe8b + OpenBSD-Commit-ID: 743af3c6e3ce5e6cecd051668f0327a01f44af29 -commit 614252b05d70f798a0929b1cd3d213030ad4d007 +commit cb4ed12ffc332d1f72d054ed92655b5f1c38f621 Author: Darren Tucker -Date: Tue Oct 18 06:29:16 2022 +1100 - - OpenSSL dev branch now identifies as 3.2.0. - -commit 195e5a65fd793a738ea8451ebfdd1919db5aff3e -Author: Damien Miller -Date: Mon Oct 17 09:41:47 2022 +1100 +Date: Sat Aug 19 07:39:08 2023 +1000 - revert c64b62338b4 and guard POLL* defines instead + Fix zlib version check for 1.3 and future version. - c64b62338b4 broke OSX builds, which do have poll.h but lack ppoll(2) - Spotted by dtucker + bz#3604. -commit bc2e480d99613bd59720edae244d1764636544c4 -Author: Damien Miller -Date: Fri Oct 14 14:52:22 2022 +1100 +commit 25b75e21f16bccdaa472ea1889b293c9bd51a87b +Author: Darren Tucker +Date: Mon Aug 14 11:10:08 2023 +1000 - undef _get{short,long} before redefining + Add 9.4 branch to CI status page. -commit 5eb796a369c64f18d55a6ae9b1fa9b35eea237fb -Author: Harmen Stoppels -Date: Thu Oct 13 16:08:46 2022 +0200 +commit 803e22eabd3ba75485eedd8b7b44d6ace79f2052 +Author: djm@openbsd.org +Date: Fri Aug 18 01:37:41 2023 +0000 - Fix snprintf configure test for clang 15 + upstream: fix regression in OpenSSH 9.4 (mux.c r1.99) that caused + + multiplexed sessions to ignore SIGINT under some circumstances. Reported by / + feedback naddy@, ok dtucker@ - Clang 15 -Wimplicit-int defaults to an error in C99 mode and above. - A handful of tests have "main(..." and not "int main(..." which caused - the tests to produce incorrect results. - -commit c64b62338b46ffa08839f05f21ad69fa6234dc17 -Author: Damien Miller -Date: Mon Oct 10 12:32:43 2022 +1100 - - skip bsd-poll.h if poll.h found; ok dtucker + OpenBSD-Commit-ID: 4d5c6c894664f50149153fd4764f21f43e7d7e5a -commit 5ee2b8ccfcf4b606f450eb0ff2305e311f68b0be +commit e706bca324a70f68dadfd0ec69edfdd486eed23a Author: djm@openbsd.org -Date: Thu Oct 6 22:42:37 2022 +0000 +Date: Wed Aug 16 16:14:11 2023 +0000 - upstream: honour user's umask if it is more restrictive then the ssh - - default (022); based on patch from Alex Henrie, ok dtucker@ deraadt@ + upstream: defence-in-depth MaxAuthTries check in monitor; ok markus - OpenBSD-Commit-ID: fe1b9e15fc9a4f49fc338e848ce14d8727abe82d + OpenBSD-Commit-ID: 65a4225dc708e2dae71315adf93677edace46c21 -commit a75cffc2700cebd3e2dd9093f7f7388d2be95cb7 -Author: Darren Tucker -Date: Fri Oct 7 03:54:56 2022 +1100 +commit d1ab7eb90474df656d5e9935bae6df0bd000d343 +Author: djm@openbsd.org +Date: Mon Aug 14 03:37:00 2023 +0000 - Add LibreSSL 3.6.0 to test suite. + upstream: add message number of SSH2_MSG_NEWCOMPRESS defined in RFC8308 - While there, bump OpenSSL to latest 1.1.1q release. + OpenBSD-Commit-ID: 6c984171c96ed67effd7b5092f3d3975d55d6028 -commit fcc0f0c0e96a30076683fea9a7c9eedc72931742 +commit fa8da52934cb7dff6f660a143276bdb28bb9bbe1 Author: Darren Tucker -Date: Thu Oct 6 21:18:16 2022 +1100 +Date: Sun Aug 13 15:01:27 2023 +1000 - Add 9.1 branch to CI status page. + Add obsd72 and obsd73 test targets. -commit ef211eee63821d894a8bf81f22bfba9f6899d0fe -Author: Darren Tucker -Date: Tue Oct 4 23:20:23 2022 +1100 +commit f9f18006678d2eac8b0c5a5dddf17ab7c50d1e9f +Author: djm@openbsd.org +Date: Thu Aug 10 23:05:48 2023 +0000 - Test commits to all branches of portable. + upstream: better debug logging of sessions' exit status - Only test OpenBSD upstream on commits to master since that's what it - tracks. - -commit fe646de03cafb6593ff4e4954bca9ec4b4b753a8 -Author: Damien Miller -Date: Wed Oct 5 03:47:26 2022 +1100 - - whitespace at EOL - -commit a6e1852d10c63a830196e82168dadd957aaf28ec -Author: Damien Miller -Date: Wed Oct 5 03:40:01 2022 +1100 - - mention libfido2 autodetection + OpenBSD-Commit-ID: 82237567fcd4098797cbdd17efa6ade08e1a36b0 -commit 7360c2c206f33d309edbaf64036c96fadf74d640 -Author: Damien Miller -Date: Wed Oct 5 03:37:36 2022 +1100 +commit a8c57bcb077f0cfdffcf9f23866bf73bb93e185c +Author: naddy@openbsd.org +Date: Thu Aug 10 14:37:32 2023 +0000 - remove mention of --with-security-key-builtin + upstream: drop a wayward comma, ok jmc@ - it is enabled by default when libfido2 is installed + OpenBSD-Commit-ID: 5c11fbb9592a29b37bbf36f66df50db9d38182c6 -commit 0ffb46f2ee2ffcc4daf45ee679e484da8fcf338c +commit e962f9b318a238db1becc53c2bf79dd3a49095b4 Author: Damien Miller -Date: Tue Oct 4 01:51:42 2022 +1100 +Date: Thu Aug 10 11:10:22 2023 +1000 - update .depend + depend -commit 657e676ff696c7bb787bffb0e249ea1be3b474e1 +commit 0fcb60bf83130dfa428bc4422b3a3ac20fb528af Author: Damien Miller -Date: Tue Oct 4 01:45:52 2022 +1100 +Date: Thu Aug 10 11:05:42 2023 +1000 - update release notes URL + update versions in RPM specs -commit f059da2b29840c0f048448809c317ce2ae014da7 +commit d0cee4298491314f09afa1c4383a66d913150b26 Author: Damien Miller -Date: Tue Oct 4 01:45:41 2022 +1100 - - crank versions in RPM spec files - -commit b51f3f172d87cbdb80ca4eb7b2149e56a7647557 -Author: djm@openbsd.org -Date: Mon Sep 26 22:18:40 2022 +0000 - - upstream: openssh-9.1 - - OpenBSD-Commit-ID: 5a467b2ee81da01a86adf1ad93b62b1728494e56 - -commit 4cf8d0c0f3030f594a238bab21a0695735515487 -Author: dtucker@openbsd.org -Date: Wed Sep 21 22:26:50 2022 +0000 +Date: Thu Aug 10 11:05:14 2023 +1000 - upstream: Fix typo. From AlexanderStohr via github PR#343. - - OpenBSD-Commit-ID: a134c9b4039e48803fc6a87f955b0f4a03181497 + update version in README -commit 8179fed3264d5919899900ed8881d5f9bb57ca33 +commit 78b4dc6684f4d35943b46b24ee645edfdb9974f5 Author: djm@openbsd.org -Date: Mon Sep 19 21:39:16 2022 +0000 +Date: Thu Aug 10 01:01:07 2023 +0000 - upstream: add RequiredRSASize to the list of keywords accepted by - - -o; spotted by jmc@ + upstream: openssh-9.4 - OpenBSD-Commit-ID: fe871408cf6f9d3699afeda876f8adbac86a035e + OpenBSD-Commit-ID: 71fc1e01a4c4ea061b252bd399cda7be757e6e35 -commit 5f954929e9f173dd1e279e07d0e8b14fa845814d -Author: Damien Miller -Date: Mon Sep 19 20:59:34 2022 +1000 +commit 58ca4f0aa8c4306ac0a629c9a85fb1efaf4ff092 +Author: Darren Tucker +Date: Thu Aug 10 11:30:24 2023 +1000 - no need for glob.h here - - it also causes portability problems + Only include unistd.h once. -commit 03d94a47207d58b3db37eba4f87eb6ae5a63168a +commit 3961ed02dc578517a9d2535128cff5c3a5460d28 Author: Damien Miller -Date: Mon Sep 19 20:59:04 2022 +1000 +Date: Thu Aug 10 09:08:49 2023 +1000 - avoid Wuninitialized false positive in gcc-12ish + wrap poll.h include in HAVE_POLL_H -commit 9d952529113831fb3071ab6e408d2726fd72e771 -Author: djm@openbsd.org -Date: Mon Sep 19 10:46:00 2022 +0000 +commit e535fbe2af893046c28adfcd787c1fdbae36a24a +Author: dtucker@openbsd.org +Date: Fri Aug 4 06:32:40 2023 +0000 - upstream: use users-groups-by-id@openssh.com sftp-server extension + upstream: Apply ConnectTimeout to multiplexing local socket - (when available) to fill in user/group names for directory listings. - Implement a client-side cache of see uid/gid=>user/group names. ok markus@ + connections. If the multiplex socket exists but the connection times out, + ssh will fall back to a direct connection the same way it would if the socket + did not exist at all. ok djm@ - OpenBSD-Commit-ID: f239aeeadfa925a37ceee36ee8b256b8ccf4466e + OpenBSD-Commit-ID: 2fbe1a36d4a24b98531b2d298a6557c8285dc1b4 -commit 8ff680368b0bccf88ae85d4c99de69387fbad7a6 -Author: djm@openbsd.org -Date: Mon Sep 19 10:43:12 2022 +0000 +commit 9d92e7b24848fcc605945f7c2e3460c7c31832ce +Author: Darren Tucker +Date: Thu Aug 3 19:35:33 2023 +1000 - upstream: sftp client library support for - - users-groups-by-id@openssh.com; ok markus@ + Fix RNG seeding for OpenSSL w/out self seeding. - OpenBSD-Commit-ID: ddb2f33a2da6349a9a89a8b5bcb9ca7c999394de + When sshd is built with an OpenSSL that does not self-seed, it would + fail in the preauth privsep process while handling a new connection. + Sanity checked by djm@ -commit 488f6e1c582212c2374a4bf8cd1b703d2e70fb8b +commit f70010d9b0b3e7e95de8aa0b961e1d74362cfb5d Author: djm@openbsd.org -Date: Mon Sep 19 10:41:58 2022 +0000 +Date: Wed Aug 2 23:04:38 2023 +0000 - upstream: extend sftp-common.c:extend ls_file() to support supplied + upstream: CheckHostIP has defaulted to 'no' for a while; make the - user/group names; ok markus@ + commented- out config option match. From Ed Maste - OpenBSD-Commit-ID: c70c70498b1fdcf158531117e405b6245863bfb0 + OpenBSD-Commit-ID: e66e934c45a9077cb1d51fc4f8d3df4505db58d9 -commit 74b77f7497dba3a58315c8f308883de448078057 -Author: djm@openbsd.org -Date: Mon Sep 19 10:40:52 2022 +0000 +commit c88a8788f9865d02b986d00405b9f0be65ad0b5a +Author: dtucker@openbsd.org +Date: Tue Aug 1 08:15:04 2023 +0000 - upstream: sftp-server(8): add a "users-groups-by-id@openssh.com" - - extension request that allows the client to obtain user/group names that - correspond to a set of uids/gids. - - Will be used to make directory listings more useful and consistent - in sftp(1). + upstream: remove unnecessary if statement. - ok markus@ + github PR#422 from eyalasulin999, ok djm@ - OpenBSD-Commit-ID: 7ebabde0bcb95ef949c4840fe89e697e30df47d3 + OpenBSD-Commit-ID: 2b6b0dde4407e039f58f86c8d2ff584a8205ea55 -commit 231a346c0c67cc7ca098360f9a554fa7d4f1eddb -Author: djm@openbsd.org -Date: Mon Sep 19 08:49:50 2022 +0000 +commit 77b8b865cd5a8c79a47605c0c5b2bacf4692c4d5 +Author: jmc@openbsd.org +Date: Fri Jul 28 05:42:36 2023 +0000 - upstream: better debugging for connect_next() + upstream: %C is a callable macro in mdoc(7) + + so, as we do for %D, escape it; - OpenBSD-Commit-ID: d16a307a0711499c971807f324484ed3a6036640 + OpenBSD-Commit-ID: 538cfcddbbb59dc3a8739604319491dcb8e0c0c9 -commit 1875042c52a3b950ae5963c9ca3774a4cc7f0380 +commit e0f91aa9c2fbfc951e9ced7e1305455fc614d3f2 Author: djm@openbsd.org -Date: Sat Sep 17 10:34:29 2022 +0000 +Date: Fri Jul 28 05:33:15 2023 +0000 - upstream: Add RequiredRSASize for sshd(8); RSA keys that fall - - beneath this limit will be ignored for user and host-based authentication. + upstream: don't need to start a command here; use ssh -N instead. - Feedback deraadt@ ok markus@ + Fixes failure on cygwin spotted by Darren - OpenBSD-Commit-ID: 187931dfc19d51873df5930a04f2d972adf1f7f1 + OpenBSD-Regress-ID: ff678a8cc69160a3b862733d935ec4a383f93cfb -commit 54b333d12e55e6560b328c737d514ff3511f1afd +commit f446a44f30bc680e0d026a4204844b02646c1c2d Author: djm@openbsd.org -Date: Sat Sep 17 10:33:18 2022 +0000 +Date: Wed May 17 05:52:01 2023 +0000 - upstream: add a RequiredRSASize for checking RSA key length in - - ssh(1). User authentication keys that fall beneath this limit will be - ignored. If a host presents a host key beneath this limit then the connection - will be terminated (unfortunately there are no fallbacks in the protocol for - host authentication). + upstream: add LTESTS_FROM variable to allow skipping of tests up to - feedback deraadt, Dmitry Belyavskiy; ok markus@ + a specific point. e.g. "make LTESTS_FROM=t-sftp" will only run the sftp.sh + test and subsequent ones. ok dtucker@ - OpenBSD-Commit-ID: 430e339b2a79fa9ecc63f2837b06fdd88a7da13a + OpenBSD-Regress-ID: 07f653de731def074b29293db946042706fcead3 -commit 07d8771bacfefbcfb37fa8a6dc6103bcc097e0ab +commit 8eb8899d612440a9b608bee7f916081d3d0b7812 Author: djm@openbsd.org -Date: Sat Sep 17 10:30:45 2022 +0000 +Date: Fri May 12 06:37:42 2023 +0000 - upstream: Add a sshkey_check_rsa_length() call for checking the - - length of an RSA key; ok markus@ + upstream: test ChrootDirectory in Match block - OpenBSD-Commit-ID: de77cd5b11594297eda82edc594b0d32b8535134 + OpenBSD-Regress-ID: a6150262f39065939f025e546af2a346ffe674c1 -commit 3991a0cf947cf3ae0f0373bcec5a90e86a7152f5 +commit e43f43d3f19516222e9a143468ea0dc1b3ab67b6 Author: djm@openbsd.org -Date: Sat Sep 17 10:11:29 2022 +0000 +Date: Fri May 12 06:36:27 2023 +0000 - upstream: actually hook up restrict_websafe; the command-line flag - - was never actually used. Spotted by Matthew Garrett + upstream: better error messages - OpenBSD-Commit-ID: 0b363518ac4c2819dbaa3dfad4028633ab9cdff1 + OpenBSD-Regress-ID: 55e4186604e80259496d841e690ea2090981bc7a -commit 30b2a7e4291fb9e357f80a237931ff008d686d3b +commit 6958f00acf3b9e0b3730f7287e69996bcf3ceda4 Author: djm@openbsd.org -Date: Fri Sep 16 06:55:37 2022 +0000 +Date: Thu Jul 27 22:26:49 2023 +0000 - upstream: correct error value + upstream: don't incorrectly truncate logged strings retrieved from + + PKCS#11 modules; based on GHPR406 by Jakub Jelen; ok markus - OpenBSD-Commit-ID: 780efcbad76281f11f14b2a5ff04eb6db3dfdad4 + OpenBSD-Commit-ID: 7ed1082f23a13b38c373008f856fd301d50012f9 -commit ac1ec9545947d9f9657259f55d04cb49d3a94c8a +commit d1ffde6b55170cd4b9a72bfd9a3f17508e6cf714 Author: djm@openbsd.org -Date: Fri Sep 16 03:33:14 2022 +0000 +Date: Thu Jul 27 22:25:17 2023 +0000 - upstream: sftp: Be a bit more clever about completions - - There are commands (e.g. "get" or "put") that accept two - arguments, a local path and a remote path. However, the way - current completion is written doesn't take this distinction into - account and always completes remote or local paths. - - By expanding CMD struct and "cmds" array this distinction can be - reflected and with small adjustment to completer code the correct - path can be completed. + upstream: make sshd_config AuthorizedPrincipalsCommand and - By Michal Privoznik, ok dtucker@ + AuthorizedKeysCommand accept the %D (routing domain) and a new %C (connection + address/port 4-tuple) as expansion sequences; ok markus - OpenBSD-Commit-ID: 1396d921c4eb1befd531f5c4a8ab47e7a74b610b + OpenBSD-Commit-ID: ee9a48bf1a74c4ace71b69de69cfdaa2a7388565 -commit 590db83384f9d99fc51c84505792d26d1ef60df9 +commit 999a2886ca1844a7a74b905e5f2c8c701f9838cd Author: djm@openbsd.org -Date: Fri Sep 16 03:13:34 2022 +0000 +Date: Thu Jul 27 22:23:05 2023 +0000 - upstream: sftp: Don't attempt to complete arguments for - - non-existent commands - - If user entered a non-existent command (e.g. because they made a - typo) there is no point in trying to complete its arguments. Skip - calling complete_match() if that's the case. + upstream: increase default KDF work-factor for OpenSSH format - From Michal Privoznik + private keys from 16 to 24; { feedback ok } x { deraadt markus } - OpenBSD-Commit-ID: cf39c811a68cde2aeb98fc85addea4000ef6b07a + OpenBSD-Commit-ID: a3afb1383f8ff0a49613d449f02395d9e8d4a9ec -commit ff9809fdfd1d9a91067bb14a77d176002edb153c -Author: djm@openbsd.org -Date: Wed Sep 14 00:14:37 2022 +0000 +commit 0fa803a1dd1c7b546c166000e23a869cf6c4ec10 +Author: Darren Tucker +Date: Thu Jul 27 02:25:09 2023 +1000 - upstream: sk_enroll: never drop SSH_SK_USER_VERIFICATION_REQD flag - - from response + Prefer OpenSSL's SHA256 in sk-dummy.so - Now that all FIDO signing calls attempt first without PIN and then - fall back to trying PIN only if that attempt fails, we can remove the - hack^wtrick that removed the UV flag from the keys returned during - enroll. + Previously sk-dummy.so used libc's (or compat's) SHA256 since it may be + built without OpenSSL. In many cases, however, including both libc's + and OpenSSL's headers together caused conflicting definitions. - By Corinna Vinschen + We tried working around this (on OpenSSL <1.1 you could define + OPENSSL_NO_SHA, NetBSD had USE_LIBC_SHA2, various #define hacks) with + varying levels of success. Since OpenSSL >=1.1 removed OPENSSL_NO_SHA + and including most OpenSSL headers would bring sha.h in, even if it + wasn't used directly this was a constant hassle. - OpenBSD-Commit-ID: 684517608c8491503bf80cd175425f0178d91d7f + Admit defeat and use OpenSSL's SHA256 unless we aren't using OpenSSL at + all. ok djm@ -commit 940dc10729cb5a95b7ee82c10184e2b9621c8a1d -Author: djm@openbsd.org -Date: Wed Sep 14 00:13:13 2022 +0000 +commit 36cdb5dbf55c99c0faad06066f56a7c341258c1f +Author: Darren Tucker +Date: Thu Jul 27 10:29:44 2023 +1000 - upstream: a little extra debugging - - OpenBSD-Commit-ID: edf1601c1d0905f6da4c713f4d9cecc7d1c0295a + Retire dfly58 test VM. Add dfly64. -commit 4b5f91cb959358141181b934156513fcb8a6c1e3 +commit 2d34205dab08ede9b0676efa57647fc49e6decbe Author: djm@openbsd.org -Date: Wed Sep 14 00:02:03 2022 +0000 +Date: Wed Jul 26 23:06:00 2023 +0000 - upstream: ssh-agent: attempt FIDO key signing without PIN and use + upstream: make ssh -f (fork after authentication) work properly in - the error to determine whether a PIN is required and prompt only if - necessary. from Corinna Vinschen + multiplexed cases (inc. ControlPersist). bz3589 bz3589 Based on patches by + Peter Chubb; ok dtucker@ - OpenBSD-Commit-ID: dd6be6a0b7148608e834ee737c3479b3270b00dd + OpenBSD-Commit-ID: a7a2976a54b93e6767dc846b85647e6ec26969ac -commit 113523bf0bc33600b07ebb083572c8c346b6fdf4 -Author: jmc@openbsd.org -Date: Sun Sep 11 06:38:11 2022 +0000 +commit 076aeda86a7ee9be8fd2f0181ec7b9729a6ceb37 +Author: naddy@openbsd.org +Date: Sun Jul 23 20:04:45 2023 +0000 - upstream: .Li -> .Vt where appropriate; from josiah frentsos, - - tweaked by schwarze - - ok schwarze + upstream: man page typos; ok jmc@ - OpenBSD-Commit-ID: 565046e3ce68b46c2f440a93d67c2a92726de8ed + OpenBSD-Commit-ID: e6ddfef94b0eb867ad88abe07cedc8ed581c07f0 -commit 86af013b56cecb5ee58ae0bd9d495cd586fc5918 -Author: jsg@openbsd.org -Date: Sat Sep 10 08:50:53 2022 +0000 +commit 135e7d5fe31f700e6dfc61ce914970c5ee7175ba +Author: jmc@openbsd.org +Date: Thu Jul 20 05:43:39 2023 +0000 - upstream: fix repeated words ok miod@ jmc@ + upstream: tweak the allow-remote-pkcs11 text; - OpenBSD-Commit-ID: 6765daefe26a6b648cc15cadbbe337596af709b7 + OpenBSD-Commit-ID: bc965460a89edf76865b7279b45cf9cbdebd558a -commit 0ba39b93b326a7d5dfab776cc9b9d326161a9b16 -Author: djm@openbsd.org -Date: Fri Sep 9 03:31:42 2022 +0000 +commit 5f83342b61d1f76c141de608ed2bd293990416bd +Author: Darren Tucker +Date: Tue Jul 25 13:00:22 2023 +1000 - upstream: notifier_complete(NULL, ...) is a noop, so no need to test - - that ctx!=NULL; from Corinna Vinschen + Handle a couple more OpenSSL no-ecc cases. - OpenBSD-Commit-ID: ade2f2e9cc519d01a586800c25621d910bce384a + ok djm@ -commit be197635329feb839865fdc738e34e24afd1fca8 -Author: Sam James -Date: Thu Sep 8 02:49:29 2022 +0100 +commit edc2ef4e418e514c99701451fae4428ec04ce538 +Author: Damien Miller +Date: Thu Jul 20 12:53:44 2023 +1000 - openbsd-compat/bsd-asprintf: add include for vsnprintf - - Fixes the following build failure with Clang 15 on musl: - ``` - bsd-asprintf.c:51:8: error: call to undeclared library function 'vsnprintf' with type 'int (char *, unsigned long, const char *, struct __va_list_tag *)'; ISO C99 and laterclang -O2 -pipe -fdiagnostics-color=always -frecord-gcc-switches -pipe -Wunknown-warning-option -Qunused-arguments -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result -Wmisleading-indentation -Wbitwise-instead-of-logical -fno-strict-aliasing -mretpoline -ftrapv -fzero-call-used-regs=all -fno-builtin-memset -fstack-protector-strong -fPIE -I. -I. -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -DSSHDIR=\"/etc/ssh\" -D_PATH_SSH_PROGRAM=\"/usr/bin/ssh\" -D_PATH_SSH_ASKPASS_DEFAULT=\"/usr/lib/misc/ssh-askpass\" -D_PATH_SFTP_SERVER=\"/usr/lib/misc/sftp-server\" -D_PATH_SSH_KEY_SIGN=\"/usr/lib/misc/ssh-keysign\" -D_PATH_SSH_PKCS11_HELPER=\"/usr/lib/misc/ssh-pkcs11-helper\" -D_PATH_SSH_SK_HELPER=\"/usr/lib/misc/ssh-sk-helper\" -D_PATH_SSH_PIDDIR=\"/run\" -D_PATH_PRIVSEP_CHROOT_DIR=\"/var/empty\" -DHAVE_CONFIG_H -c cipher-aes.c -o cipher-aes.o - do not support - implicit function declarations [-Wimplicit-function-declaration] - ret = vsnprintf(string, INIT_SZ, fmt, ap2); - ^ - bsd-asprintf.c:51:8: note: include the header or explicitly provide a declaration for 'vsnprintf' - 1 error generated. - ``` + depend -commit 6cb6f660bb35f77a0456dd2581ddf39c29398a5e -Author: Darren Tucker -Date: Fri Sep 2 16:43:27 2022 +1000 +commit 51fda734e0d3c2df256fc03e8b060c4305be6e59 +Author: Damien Miller +Date: Thu Jul 20 12:53:21 2023 +1000 - Remove DEF_WEAK, it's already in defines.h. + Bring back OPENSSL_HAS_ECC to ssh-pkcs11-client -commit ce39e7d8b70c4726defde5d3bc4cb7d40d131153 -Author: Darren Tucker -Date: Fri Sep 2 14:28:14 2022 +1000 +commit 099cdf59ce1e72f55d421c8445bf6321b3004755 +Author: djm@openbsd.org +Date: Wed Jul 19 14:03:45 2023 +0000 - Resync arc4random with OpenBSD. + upstream: Separate ssh-pkcs11-helpers for each p11 module - This brings us up to current, including djm's random-reseeding change, - as prompted by logan at cyberstorm.mu in bz#3467. It brings the - platform-specific hooks from LibreSSL Portable, simplified to match our - use case. ok djm@. - -commit beaddde26f30e2195b8aa4f3193970e140e17305 -Author: Darren Tucker -Date: Fri Sep 2 14:20:04 2022 +1000 - - Move OPENBSD ORIGINAL marker. + Make ssh-pkcs11-client start an independent helper for each provider, + providing better isolation between modules and reliability if a single + module misbehaves. + + This also implements reference counting of PKCS#11-hosted keys, + allowing ssh-pkcs11-helper subprocesses to be automatically reaped + when no remaining keys reference them. This fixes some bugs we have + that make PKCS11 keys unusable after they have been deleted, e.g. + https://bugzilla.mindrot.org/show_bug.cgi?id=3125 - Putting this after the copyright statement (which doesn't change) - instead of before the version identifier (which does) prevents merge - conflicts when resyncing changes. + ok markus@ + + OpenBSD-Commit-ID: 0ce188b14fe271ab0568f4500070d96c5657244e -commit c83e467ead67a8cb48ef4bec8085d6fb880a2ff4 -Author: Darren Tucker -Date: Fri Sep 2 14:17:28 2022 +1000 +commit 29ef8a04866ca14688d5b7fed7b8b9deab851f77 +Author: djm@openbsd.org +Date: Wed Jul 19 14:02:27 2023 +0000 - Remove arc4random_uniform from arc4random.c + upstream: Ensure FIDO/PKCS11 libraries contain expected symbols + + This checks via nlist(3) that candidate provider libraries contain one + of the symbols that we will require prior to dlopen(), which can cause + a number of side effects, including execution of constructors. - This was previously moved into its own file (matching OpenBSD) which - prematurely committed in commit 73541f2. + Feedback deraadt; ok markus + + OpenBSD-Commit-ID: 1508a5fbd74e329e69a55b56c453c292029aefbe -commit 5f45c2395c60865e59fa44152ff1d003a128c5bc +commit 1f2731f5d7a8f8a8385c6031667ed29072c0d92a Author: djm@openbsd.org -Date: Fri Sep 2 04:20:02 2022 +0000 +Date: Wed Jul 19 13:56:33 2023 +0000 - upstream: sk-usbhid: fix key_lookup() on tokens with built-in UV + upstream: Disallow remote addition of FIDO/PKCS11 provider + + libraries to ssh-agent by default. - explicitly test whether the token performs built-in UV (e.g. biometric - tokens) and enable UV in that case. From Pedro Martelletto via GHPR#388 + The old behaviour of allowing remote clients from loading providers + can be restored using `ssh-agent -O allow-remote-pkcs11`. + + Detection of local/remote clients requires a ssh(1) that supports + the `session-bind@openssh.com` extension. Forwarding access to a + ssh-agent socket using non-OpenSSH tools may circumvent this control. + + ok markus@ - OpenBSD-Commit-ID: 007eb7e387d27cf3029ab06b88224e03eca62ccd - -commit 03277a4aa49b80af541a3e691f264c0c0d8f9cec -Author: Darren Tucker -Date: Wed Aug 31 20:26:30 2022 +1000 - - Move sftp from valgrind-2 to 3 to rebalance. + OpenBSD-Commit-ID: 4c2bdf79b214ae7e60cc8c39a45501344fa7bd7c -commit fcf5365da69c516817321ba89c3a91df98d098df +commit 892506b13654301f69f9545f48213fc210e5c5cc Author: djm@openbsd.org -Date: Wed Aug 31 02:56:40 2022 +0000 +Date: Wed Jul 19 13:55:53 2023 +0000 - upstream: whitespace + upstream: terminate process if requested to load a PKCS#11 provider - OpenBSD-Commit-ID: c2bcbf93610d3d62ed206cdf9bf9ff98c6aaf232 + that isn't a PKCS#11 provider; from / ok markus@ + + OpenBSD-Commit-ID: 39532cf18b115881bb4cfaee32084497aadfa05c -commit e60136a3d7a223dd8e84ba8a6895bc3142360993 +commit f3f56df8ec476b2de6cbdbdfdb77a2a61087829d Author: Damien Miller -Date: Mon Aug 29 13:27:45 2022 +1000 +Date: Wed Jul 19 12:07:18 2023 +1000 - additional keys + agent_fuzz doesn't want stdint.h conditionalised -commit 2b02dcb505288c462d1b5dd1ac04e603d01340eb +commit 750911fd31d307a767cc86e3bfa90bbbb77b1a25 Author: Damien Miller -Date: Mon Aug 29 13:23:43 2022 +1000 - - cross-sign allowed_signers with PGP key - - Provides continuity of trust from legacy PGP release key to - the SSHSIG signing keys that we will use henceforth for git - signing. - -commit 51b345f177ae981b8755f6bdf8358b1cc5e83d67 -Author: Darren Tucker -Date: Sat Aug 27 21:49:27 2022 +1000 +Date: Tue Jul 18 15:41:12 2023 +1000 - Add libcrypt-devel to cygwin-release deps. + conditionalise stdint.h inclusion on HAVE_STDINT_H - Based on feedback from vinschen at redhat.com. - -commit 9f81736cf16dd8dda1c8942f1973a5f80b8cd78c -Author: Darren Tucker -Date: Sat Aug 27 09:37:40 2022 +1000 - - Add Windows 2022 test targets. + fixes build on AIX5 at least -commit 85e1a69243f12be8520438ad6a3cfdc0b7fcbb2d -Author: Darren Tucker -Date: Fri Aug 26 16:26:06 2022 +1000 +commit ff047504fa6e008c4092f8929881816b8993bea0 +Author: Damien Miller +Date: Tue Jul 18 15:30:45 2023 +1000 - Add cygwin-release test target. + conditionalise match localnetwork on ifaddrs.h - This also moves the cygwin package install from the workflow file to - setup_ci.sh so that we can install different sets of Cygwin packages - for different test configs. + Fixes build breakage on platforms that lack getifaddrs() -commit 92382dbe8bf9ea1225b16858f9b9b208c15c7e8d +commit b87b03282e466ca2927954ce93f5dbf0bfdc68f6 Author: djm@openbsd.org -Date: Fri Aug 26 08:16:27 2022 +0000 +Date: Mon Jul 17 06:16:33 2023 +0000 - upstream: whitespace + upstream: missing match localnetwork negation check - OpenBSD-Commit-ID: a5d015efbfd228dc598ffdef612d2da3a579e5d8 + OpenBSD-Commit-ID: 9a08ed8dae27d3f38cf280f1b28d4e0ff41a737a -commit 70a5de0a50e84d7250eb4e4537f765599f64c4af -Author: djm@openbsd.org -Date: Fri Aug 26 08:12:56 2022 +0000 +commit 6d6e185ba29ef4274164b77eab4dc763907f8821 +Author: jmc@openbsd.org +Date: Mon Jul 17 05:41:53 2023 +0000 - upstream: whitespace + upstream: - add -P to usage() - sync the arg name to -J in usage() + + with that in ssh.1 - reformat usage() to match what "man ssh" does on 80width - OpenBSD-Commit-ID: d297e4387935d4aef091c5e9432578c2e513f538 + OpenBSD-Commit-ID: 5235dd7aa42e5bf90ae54579d519f92fc107036e -commit 3a683a19fd116ea15ebf8aa13d02646cceb302a9 -Author: Damien Miller -Date: Fri Aug 26 14:23:55 2022 +1000 +commit f1a9898283a0638667b587ee4a950afd61ab51b0 +Author: jmc@openbsd.org +Date: Mon Jul 17 05:38:10 2023 +0000 - initial list of allowed signers + upstream: -P before -p in SYNOPSIS; + + OpenBSD-Commit-ID: 535f5257c779e26c6a662a038d241b017f8cab7c -commit 6851f4b8c3fc1b3e1114c56106e4dc31369c8513 -Author: Darren Tucker -Date: Fri Aug 19 17:22:18 2022 +1000 +commit eef4d7e873568e1c84c36bb4034e2c3378250a61 +Author: jsg@openbsd.org +Date: Mon Jul 17 05:36:14 2023 +0000 - Install Cygwin packages based on OS not config. + upstream: configuation -> configuration + + OpenBSD-Commit-ID: 4776ced33b780f1db0b2902faec99312f26a726b -commit f96480906893ed93665df8cdf9065865c51c1475 +commit dc1dbe94cf6532bd546a3373ad436404f8850e5f Author: djm@openbsd.org -Date: Fri Aug 19 06:07:47 2022 +0000 +Date: Mon Jul 17 05:26:38 2023 +0000 - upstream: attemp FIDO key signing without PIN and use the error + upstream: move other RCSIDs to before their respective license blocks - code returned to fall back only if necessary. Avoids PIN prompts for FIDO - tokens that don't require them; part of GHPR#302 + too no code change - OpenBSD-Commit-ID: 4f752aaf9f2e7c28bcaaf3d4f8fc290131bd038e + OpenBSD-Commit-ID: ef5bf46b57726e4260a63b032b0b5ac3b4fe9cd4 -commit 5453333b5d28e313284cb9aae82899704103f98d +commit ebe11044681caff78834ca6b78311ad19c1860b8 Author: djm@openbsd.org -Date: Fri Aug 19 05:53:28 2022 +0000 +Date: Mon Jul 17 05:22:30 2023 +0000 - upstream: remove incorrect check that can break enrolling a + upstream: Move RCSID to before license block and away from #includes, - resident key (introduced in r1.40) + where it caused merge conflict in -portable for each commit :( - OpenBSD-Commit-ID: 4cab364d518470e29e624af3d3f9ffa9c92b6f01 + OpenBSD-Commit-ID: 756ebac963df3245258b962e88150ebab9d5fc20 -commit ff89b1bed80721295555bd083b173247a9c0484e -Author: dtucker@openbsd.org -Date: Fri Aug 19 04:02:46 2022 +0000 +commit 05c08e5f628de3ecf6f7ea20947735bcfa3201e0 +Author: djm@openbsd.org +Date: Mon Jul 17 05:20:15 2023 +0000 - upstream: Strictly enforce the maximum allowed SSH2 banner size in + upstream: return SSH_ERR_KRL_BAD_MAGIC when a KRL doesn't contain a - ssh-keyscan and prevent a one-byte buffer overflow. Patch from Qualys, ok - djm@ + valid magic number and not SSH_ERR_MESSAGE_INCOMPLETE; the former is needed + to fall back to text revocation lists in some cases; fixes t-cert-hostkey. - OpenBSD-Commit-ID: 6ae664f9f4db6e8a0589425f74cd0bbf3aeef4e4 - -commit 1b470b9036639cef4f32fb303bb35ea0b711178d -Author: Darren Tucker -Date: Fri Aug 19 15:18:09 2022 +1000 - - Fix cygwin conditional steps. - -commit fd6ee741ab16714b7035d60aca924123ba28135a -Author: Darren Tucker -Date: Fri Aug 19 15:12:57 2022 +1000 - - Add a bit more debug output. + OpenBSD-Commit-ID: 5c670a6c0f027e99b7774ef29f18ba088549c7e1 -commit a9305c4c739f4d91a3d3a92c0b6d4949404a36c5 -Author: Darren Tucker -Date: Fri Aug 12 15:08:47 2022 +1000 +commit c6fad2c3d19b74f0bd0af1ef040fc74f3a1d9ebb +Author: Damien Miller +Date: Mon Jul 17 14:56:14 2023 +1000 - Add Cygwin (on windows-2019) test target. - - In addition to installing the requisite Cygwin packages, we also need to - explicitly invoke "sh" for steps that run other scripts since the runner - environment doesn't understand #! paths. + avoid AF_LINK on platforms that don't define it -commit 5062ad48814b06162511c4f5924a33d97b6b2566 +commit 919bc3d3b712c920de1ae6be5ac6561c98886d7e Author: djm@openbsd.org -Date: Fri Aug 19 03:06:30 2022 +0000 +Date: Mon Jul 17 04:08:31 2023 +0000 - upstream: double free() in error path; from Eusgor via GHPR333 + upstream: Add support for configuration tags to ssh(1). - OpenBSD-Commit-ID: 39f35e16ba878c8d02b4d01d8826d9b321be26d4 - -commit 5a5c580b48fc6006bdfa731fc2f6d4945c2c0e4e -Author: Darren Tucker -Date: Thu Aug 18 21:36:39 2022 +1000 - - Check for perms to run agent-getpeereid test. + This adds a ssh_config(5) "Tag" directive and corresponding + "Match tag" predicate that may be used to select blocks of + configuration similar to the pf.conf(5) keywords of the same + name. - Ubuntu 22.04 defaults to private home dirs which prevents "nobody" - running ssh-add during the agent-getpeereid test. Check for this and - add the necessary permissions. - -commit cd06a76b7ccc706e2bb4f1cc4aa9e9796a28a812 -Author: Damien Miller -Date: Wed Aug 17 16:04:16 2022 +1000 - - on Cygwin, prefer WinHello FIDO device + ok markus - If no FIDO device was explictly specified, then prefer the - windows://hello FIDO device. An exception to this is when - probing resident FIDO keys, in which case hardware FIDO - devices are preferred. + OpenBSD-Commit-ID: dc08358e70e702b59ac3e591827e5a96141b06a3 -commit 47f72f534ac5cc2cd3027675a3df7b00a8f77575 +commit 3071d85a47061c1bdaf11a0ac233b501ecba862c Author: djm@openbsd.org -Date: Wed Aug 17 06:01:57 2022 +0000 +Date: Mon Jul 17 04:04:36 2023 +0000 - upstream: add an extra flag to sk_probe() to indicate whether we're + upstream: add a "match localnetwork" predicate. - probing for a FIDO resident key or not. Unused here, but will make like - easier for portable + This allows matching on the addresses of available network interfaces + and may be used to vary the effective client configuration based on + network location (e.g. to use a ProxyJump when not on a particular + network). - OpenBSD-Commit-ID: 432c8ff70e270378df9dbceb9bdeaa5b43b5a832 - -commit edb0bcb3c79b16031dc87a8e57aecc3c4a3414f0 -Author: jmc@openbsd.org -Date: Tue Aug 16 20:24:08 2022 +0000 - - upstream: use .Cm for "sign"; from josiah frentsos + ok markus@ - OpenBSD-Commit-ID: 7f80a53d54857ac6ae49ea6ad93c5bd12231d1e4 + OpenBSD-Commit-ID: cffb6ff9a3803abfc52b5cad0aa190c5e424c139 -commit cccb011e130cbbac538b1689d10e4a067298df8b -Author: Corinna Vinschen -Date: Thu Aug 11 20:19:35 2022 +0200 +commit beec17bb311365b75a0a5941418d4b96df7d7888 +Author: djm@openbsd.org +Date: Mon Jul 17 04:01:10 2023 +0000 - Revert "check_sk_options: add temporary WinHello workaround" - - Cygwin now comes with libfido2 1.11.0, so this workaround - isn't required anymore. + upstream: remove vestigal support for KRL signatures - This reverts commit 242c044ab111a37aad3b0775727c36a4c5f0102c. + When the KRL format was originally defined, it included support for + signing of KRL objects. However, the code to sign KRLs and verify KRL + signatues was never completed in OpenSSH. - Signed-off-by: Corinna Vinschen - -commit 9468cd7cf9d989dfa2ac20e2a0268ba6e93bfa5a -Author: Corinna Vinschen -Date: Thu Aug 11 20:18:17 2022 +0200 - - fido_dev_is_winhello: return 0, not "false" + Now, some years later, we have SSHSIG support in ssh-keygen that is + more general, well tested and actually works. So this removes the + semi-finished KRL signing/verification support from OpenSSH and + refactors the remaining code to realise the benefit - primarily, we + no longer need to perform multiple parsing passes over KRL objects. - "false" is not used anywhere in OpenSSH, so return 0 like - everywhere else. + ok markus@ - Signed-off-by: Corinna Vinschen + OpenBSD-Commit-ID: 517437bab3d8180f695c775410c052340e038804 -commit 730a80609472ee0451c99482d75c9c41f3ebc42d +commit 449566f64c21b4578d5c0c431badd0328adc53ed Author: djm@openbsd.org -Date: Fri Aug 12 05:20:28 2022 +0000 +Date: Mon Jul 17 03:57:21 2023 +0000 - upstream: sftp-server: support home-directory request + upstream: Support for KRL extensions. - Add support to the sftp-server for the home-directory extension defined - in draft-ietf-secsh-filexfer-extensions-00. This overlaps a bit with the - existing expand-path@openssh.com, but uses a more official protocol name, - and so is a bit more likely to be implemented by non-OpenSSH clients. + This defines wire formats for optional KRL extensions and implements + parsing of the new submessages. No actual extensions are supported at + this point. - From Mike Frysinger, ok dtucker@ + ok markus - OpenBSD-Commit-ID: bfc580d05cc0c817831ae7ecbac4a481c23566ab - -commit 5e820bf79ce3ce99ef7e98b0ab642b0a0a4f396c -Author: Darren Tucker -Date: Fri Aug 12 14:56:55 2022 +1000 - - Replace deprecated ubuntu-18.04 runners with 22.04 + OpenBSD-Commit-ID: ae2fcde9a22a9ba7f765bd4f36b3f5901d8c3fa7 -commit 87b0d9c1b789d3ff958ec45df2ac912e24461bae -Author: Darren Tucker -Date: Thu Aug 11 22:48:23 2022 +1000 +commit 18ea857770e84825a3a6238bb37f54864487b59f +Author: dtucker@openbsd.org +Date: Fri Jul 14 07:44:21 2023 +0000 - Add a timegm implementation from Heimdal via Samba. + upstream: Include stdint.h for SIZE_MAX. Fixes OPENSSL=no build. - Fixes build on (at least Solaris 10). + OpenBSD-Commit-ID: e7c31034a5434f2ead3579b13a7892960651e6b0 -commit d0c4fa58594577994921b593f10037c5282597ca +commit 20b768fcd13effe0f2d3619661b6c8592c773553 Author: Darren Tucker -Date: Thu Aug 11 14:23:58 2022 +1000 +Date: Fri Jul 14 17:07:32 2023 +1000 - Rerun tests if any .github config file changes. + Fix typo in declaration of nmesg. -commit 113fe6c77ab43769fc61e953d07cb619fd7ea54b -Author: Darren Tucker -Date: Thu Aug 11 13:33:51 2022 +1000 +commit 4b94d09542e36ebde2eb9ad89bc68431609932de +Author: Damien Miller +Date: Fri Jul 14 15:34:47 2023 +1000 - Skip hostbased during Valgrind tests. - - Valgrind doesn't let ssh exec ssh-keysign (because it's setuid) so skip - it during the Valgrind based tests. + portable-specific int overflow defence-in-depth - See https://bugs.kde.org/show_bug.cgi?id=119404 for a discussion of this - (ironically there the problematic binary was ssh(1) back when it could - still be setuid). + These too are unreachable, but we want the code to be safe regardless of + context. Reported by Yair Mizrahi @ JFrog -commit b98a42afb69d60891eb0488935990df6ee571c4d +commit 2ee48adb9fc8692e8d6ac679dcc9f35e89ad68f0 Author: djm@openbsd.org -Date: Thu Aug 11 01:57:50 2022 +0000 +Date: Fri Jul 14 05:31:44 2023 +0000 - upstream: add some tests for parse_absolute_time(), including cases + upstream: add defence-in-depth checks for some unreachable integer - where it is forced to the UTC timezone. bz3468 ok dtucker + overflows reported by Yair Mizrahi @ JFrog; feedback/ok millert@ - OpenBSD-Regress-ID: ea07ca31c2f3847a38df028ca632763ae44e8759 + OpenBSD-Commit-ID: 52af085f4e7ef9f9d8423d8c1840a6a88bda90bd -commit ec1ddb72a146fd66d18df9cd423517453a5d8044 +commit 4b43bc358ae6f6b19a973679246dc5172f6ac41b Author: djm@openbsd.org -Date: Thu Aug 11 01:56:51 2022 +0000 +Date: Mon Jul 10 04:51:26 2023 +0000 - upstream: allow certificate validity intervals, sshsig verification - - times and authorized_keys expiry-time options to accept dates in the UTC time - zone in addition to the default of interpreting them in the system time zone. - YYYYMMDD and YYMMDDHHMM[SS] dates/times will be interpreted as UTC if - suffixed with a 'Z' character. - - Also allow certificate validity intervals to be specified in raw - seconds-since-epoch as hex value, e.g. -V 0x1234:0x4567890. This - is intended for use by regress tests and other tools that call - ssh-keygen as part of a CA workflow. - - bz3468 ok dtucker + upstream: misplaced debug message - OpenBSD-Commit-ID: 454db1cdffa9fa346aea5211223a2ce0588dfe13 + OpenBSD-Commit-ID: d0f12af0a5067a756aa707bc39a83fa6f58bf7e5 -commit 4df246ec75751da7eb925e1880498300d8bda187 -Author: Darren Tucker -Date: Thu Aug 11 10:23:55 2022 +1000 +commit 8c7203bcee4c4f98a22487b4631fe068b992099b +Author: Damien Miller +Date: Wed Jul 12 11:41:19 2023 +1000 - Fix conditional for running hostbased tests. + replace deprecate selinux matchpathcon function + + This function is apparently deprecated. Documentation on what is the + supposed replacement is is non-existent, so this follows the approach + glibc used https://sourceware.org/git/?p=glibc.git;a=patch;h=f278835f59 + + ok dtucker@ -commit 2580916e48721802220c61ce9e0df1297c00bc07 -Author: Damien Miller -Date: Thu Aug 11 08:58:28 2022 +1000 +commit 7e8800f5d701efffa39ccb63ca1e095ea777c31a +Author: dtucker@openbsd.org +Date: Thu Jul 6 22:17:59 2023 +0000 - fix SANDBOX_SECCOMP_FILTER_DEBUG + upstream: minleft and maxsign are u_int so cast appropriately. Prompted + + by github PR#410, ok deraadt. + + OpenBSD-Commit-ID: 0514cd51db3ec60239966622a0d3495b15406ddd -commit fdbd5bf507fc271ff813714fab8a72ff2c6cb5ca -Author: Darren Tucker -Date: Wed Aug 10 17:35:52 2022 +1000 +commit 94842bfe9b09fc93189c6ed0dc9bbebc1d44a426 +Author: dlg@openbsd.org +Date: Tue Jul 4 03:59:21 2023 +0000 - Test hostbased auth on github runners. + upstream: add support for unix domain sockets to ssh -W + + ok djm@ dtucker@ + + OpenBSD-Commit-ID: 3e6d47567b895c7c28855c7bd614e106c987a6d8 -commit 7e2f51940ba48a1c0fae1107801ea643fa83c971 -Author: Darren Tucker -Date: Wed Aug 10 17:25:24 2022 +1000 +commit a95fc5eed09a0238fb127b6c50e8498432b79dae +Author: David Seifert +Date: Fri May 12 14:06:01 2023 +0200 - Rename our getentropy to prevent possible loops. + gss-serv.c: `MAXHOSTNAMELEN` -> `HOST_NAME_MAX` + + `MAXHOSTNAMELEN` is not defined in POSIX, which breaks on musl: + https://pubs.opengroup.org/onlinepubs/9699919799/functions/gethostname.html - Since arc4random seeds from getentropy, and we use OpenSSL for that - if enabled, there's the possibility that if we build on a system that - does not have getentropy then run on a system that does have it, then - OpenSSL could end up calling our getentropy and getting stuck in a loop. - Pointed out by deraadt@, ok djm@ + Bug: https://bugs.gentoo.org/834044 -commit 7a01f61be8d0aca0e975e7417f26371495fe7674 +commit 8a6cd08850f576e7527c52a1b086cae82fab290e Author: Darren Tucker -Date: Mon Aug 8 12:17:04 2022 +1000 +Date: Fri Jun 23 09:49:02 2023 +1000 - Actually put HAVE_STDINT_H around the stdint.h. + Update runner OS version for hardenedmalloc test. + + Hardenedmalloc dropped support for "legacy glibc" versions in their + 64dad0a69 so use a newer Ubuntu version for the runner for that test. -commit 73541f29f0b50480da6c20dceb7a7191bd8ea7d3 -Author: Darren Tucker -Date: Mon Aug 8 10:30:34 2022 +1000 +commit cfca6f17e64baed6822bb927ed9f372ce64d9c5b +Author: Damien Miller +Date: Thu Jun 22 15:04:03 2023 +1000 - Give unused param a name. + handle sysconf(SC_OPEN_MAX) returning > INT_MAX; - Fixes builds on platforms that do have fido2 but don't have - fido_dev_is_winhello. + bz3581; ok dtucker -commit 2a108c0ea960381bd9b14ee0d84e818a23df4482 +commit c1c2ca1365b3f7b626683690bd2c68265f6d8ffd Author: djm@openbsd.org -Date: Fri Aug 5 05:01:40 2022 +0000 +Date: Wed Jun 21 05:10:26 2023 +0000 - upstream: don't prompt for FIDO passphrase before attempting to enroll + upstream: better validate CASignatureAlgorithms in ssh_config and + + sshd_config. - the credential, just let the enroll operating fail and we'll attempt to get a - PIN anyway. Might avoid some unneccessary PIN prompts. + Previously this directive would accept certificate algorithm names, but + these were unusable in practice as OpenSSH does not support CA chains. - Part of GHPR#302 from Corinna Vinschen; ok dtucker@ + part of bz3577; ok dtucker@ - OpenBSD-Commit-ID: bd5342ffc353ee37d39617906867c305564d1ce2 + OpenBSD-Commit-ID: a992d410c8a78ec982701bc3f91043dbdb359912 -commit 2886975c0ad9244e60dc5e4be34fde3aa573a4b5 -Author: Corinna Vinschen -Date: Fri Feb 11 14:33:41 2022 +0100 +commit 4e73cd0f4ab3e5b576c56cac9732da62c8fc0565 +Author: djm@openbsd.org +Date: Wed Jun 21 05:08:32 2023 +0000 - sk_sign: set FIDO2 uv attribute explicitely for WinHello + upstream: make `ssh -Q CASignatureAlgorithms` only list signature - WinHello via libfido2 performs user verification by default. - However, if we stick to that, there's no way to differentiate - between keys created with or without "-O verify-required". - Set FIDO2 uv attribute explicitely to FIDO_OPT_FALSE, then check - if user verification has been requested. + algorithms that are valid for CA signing. Previous behaviour was to list all + signing algorithms, including certificate algorithms (OpenSSH certificates do + not support CA chains). part of bz3577; ok dtucker@ - Signed-off-by: Corinna Vinschen + OpenBSD-Commit-ID: 99c2b072dbac0f44fd1f2269e3ff6c1b5d7d3e59 -commit 242c044ab111a37aad3b0775727c36a4c5f0102c -Author: Corinna Vinschen -Date: Tue Feb 15 11:28:08 2022 +0100 +commit a69062f1695ac9c3c3dea29d3044c72aaa6af0ea +Author: djm@openbsd.org +Date: Wed Jun 21 05:06:04 2023 +0000 - check_sk_options: add temporary WinHello workaround + upstream: handle rlimits > INT_MAX (rlim_t is u64); ok dtucker - Up to libfido 1.10.0, WinHello advertises "clientPin" rather - than "uv" capability. This is fixed in 1.11.0. For the time - being, workaround it here. + bz3581 - Signed-off-by: Corinna Vinschen + OpenBSD-Commit-ID: 31cf59c041becc0e5ccb0a77106f812c4cd1cd74 -commit 78774c08cc4b4997382975b0f414a86e06b6780c -Author: Corinna Vinschen -Date: Thu Feb 10 18:19:29 2022 +0100 +commit 8d33f2aa6bb895a7f85a47189913639086347b75 +Author: djm@openbsd.org +Date: Tue Jun 20 23:59:33 2023 +0000 - compat code for fido_dev_is_winhello() + upstream: prepare for support for connecting to unix domain sockets - Signed-off-by: Corinna Vinschen - -commit 3d3a932a019aedfb891e0779bb4990cd5008a390 -Author: Darren Tucker -Date: Fri Aug 5 13:12:27 2022 +1000 - - Factor out getrnd() and rename to getentropy(). + using ssh -W by explicitly decoding PORT_STREAMLOCAL (a negative number) from + the u32 that's passed over the multiplexing socket; previously code would + just cast, which is UB. - Factor out the arc4random seeding into its own file and change the - interface to match getentropy. Use native getentropy if available. - This will make it easier to resync OpenBSD changes to arc4random. - Prompted by bz#3467, ok djm@. - -commit 9385d277b787403be9dfcb229cf372202496d2f3 -Author: Darren Tucker -Date: Thu Aug 4 18:55:48 2022 +1000 - - Include CHANNEL and FIDO2 libs in configure output + OpenBSD-Commit-ID: e5ac5f40d354096c51e8c118a5c1b2d2b7a31384 -commit 141535b904b6fba01724444f38193a8599201f82 +commit b4ac435b4e67f8eb5932d8f59eb5b3cf7dc38df0 Author: djm@openbsd.org -Date: Mon Aug 1 11:09:26 2022 +0000 +Date: Tue Jun 20 00:05:09 2023 +0000 - upstream: avoid double-free in error path introduced in r1.70; report + upstream: reset comment=NULL for each key in do_fingerprint(); - and fix based on GHPR#332 by v-rzh ok dtucker@ + fixes "no comment" not showing on when running `ssh-keygen -l` on multiple + keys where one has a comment and other following keys do not. Patch from + Markus Kuhn via GHPR407, bz3580 - OpenBSD-Commit-ID: 3d21aa127b1f37cfc5bdc21461db369a663a951f - -commit dba7099ffcba3ca07b3946f017ba6a4c3158d9b1 -Author: Darren Tucker -Date: Wed Jul 27 18:40:12 2022 +1000 - - Remove deprecated MacOS 10.15 runners. + OpenBSD-Commit-ID: 3cce84456fdcd67dc6b84e369f92c6686d111d9b -commit 722a56439aa5972c830e4a9a724cf52aff4a950a -Author: Darren Tucker -Date: Wed Jul 27 18:31:14 2022 +1000 +commit b53a809a549dcd4fbde554c6aa283e597b15ea33 +Author: millert@openbsd.org +Date: Mon Jun 5 13:24:36 2023 +0000 - Move stale-configure check as early as possible. + upstream: Store timeouts as int, not u_int as they are limited to - We added a check in Makefile to catch the case where configure needs to - be rebuilt, however this did not happen until a build was attempted in - which case all of the work done by configure was wasted. Move this check - to the start of configure to catch it as early as possible. ok djm@ - -commit 099d6b56288b421ba38531d26dc1bd6bb685e311 -Author: Darren Tucker -Date: Fri Jul 22 10:47:19 2022 +1000 - - Move libcrypto into CHANNELLIBS. + INT_MAX. Fixes sign compare warnings systems with 32-bit time_t due to type + promotion. OK djm@ - This will result in sftp, sftp-server and scp no longer being linked - against libcrypto. ok djm@ + OpenBSD-Commit-ID: 48081e9ad35705c5f1705711704a4c2ff94e87b7 -commit 1bdf86725b77733bb5f17c54888b88a10b2f6538 -Author: Darren Tucker -Date: Fri Jul 22 10:45:47 2022 +1000 +commit 2709809fd616a0991dc18e3a58dea10fb383c3f0 +Author: Philip Hands +Date: Wed May 24 19:41:14 2023 +0200 - Remove seed_rng calls from scp, sftp, sftp-server. + fixup! if -s & -p specified, mention 'sftp -P' on - These binaries don't use OpenSSL's random functions. The next step - will be to stop linking them against libcrypto. ok djm@ - -commit d73f77b8cb9b422f1ac4facee7890aa10ff2bc21 -Author: Darren Tucker -Date: Fri Jul 22 09:51:51 2022 +1000 - - Group libcrypto and PRNGD checks together. + success - They're related more than the libcrypt or libiaf checks which are - currently between them. ok djm@ + SSH-Copy-ID-Upstream: 32686e7c65b4fa2846e474d3315102dfa0f043b0 -commit f117e372b3f42f2fbdb0a578d063b2609ab58e1f +commit 204e0bf05161b7641500d7ab266c21217412379f Author: Darren Tucker -Date: Fri Jul 22 09:24:45 2022 +1000 +Date: Tue Aug 3 21:25:48 2021 +1000 - Do not link scp, sftp and sftp-server w/ zlib. + Make ssh-copy-id(1) consistent with OpenSSH. - Some of our binaries (eg sftp, sftp-server, scp) do not interact with - the channels code and thus do use libraries such as zlib and libcrypto - although they are linked with them. This adds a CHANNELLIBS and starts - by moving zlib into it, which means the aformentioned binaries are no - longer linked against zlib. ok djm@ - -commit 800c2483e68db38bd1566ff69677124be974aceb -Author: Darren Tucker -Date: Mon Jul 25 21:49:04 2022 +1000 - - Remove workarounds for OpenSSL missing AES-CTR. + This makes the ssh-copy-id man page more consistent with the rest of the + OpenSSH man pages: + - new sentence, new line + - no sentences >80 + - N.B. -> NB + - zap unused .Pp + - zap trailing whitespace - We have some compatibility hacks that were added to support OpenSSL - versions that do not support AES CTR mode. Since that time, however, - the minimum OpenSSL version that we support has moved to 1.0.1 which - *does* have CTR, so this is no longer needed. ok djm@ - -commit b7c56b65c12f51fe0dbae798d19c8f58224a5d95 -Author: Darren Tucker -Date: Mon Jul 25 21:43:00 2022 +1000 - - Remove workarounds for OpenSSL missing AES-GCM. + Report from Debian via mindrot bz#3331, diff from jmc at openbsd.org. - We have some compatibility hacks that were added to support OpenSSL - versions that do not support AES GCM mode. Since that time, however, - the minimum OpenSSL version that we support has moved to 1.0.1 which - *does* have GCM, so this is no longer needed. ok djm@ + SSH-Copy-ID-Upstream: d8974cfb6242316460ed22a1ccc662800a50c5d3 -commit 5a4a9f7a968fbf92cc1eac519c65638e79ae9f1f -Author: dtucker@openbsd.org -Date: Mon Jul 25 07:12:45 2022 +0000 +commit 9de79df66d1430d290fab670bb4b18612875e518 +Author: Philip Hands +Date: Wed May 24 11:45:43 2023 +0200 - upstream: Restore missing "!" in TEST_SSH_ELAPSED_TIMES test. + if -s & -p specified, mention 'sftp -P' on success - OpenBSD-Regress-ID: 38783f9676ec348c5a792caecee9a16e354b37b0 - -commit 0ff886be132299386cc29d87c2aa16ff68a1aa08 -Author: dtucker@openbsd.org -Date: Sun Jul 24 23:29:10 2022 +0000 - - upstream: Test TEST_SSH_ELAPSED_TIMES for empty string not + This was inspired by this: + https://github.com/openssh/openssh-portable/pull/321 + but I thought that it was better to not do the sed patching. - executable. No-op on most platforms but should prevent warnings in -portable - on systems that don't have 'date %s'. + BTW the reason one can get away with using $SSH_OPTS throughout, despite + the lowercase -p in there, even if sftp is in use, is that the sftp call + is using the already-established ssh master connection, so the port was + passed to the earlier ssh. - OpenBSD-Regress-ID: e39d79867b8065e33d0c5926fa1a31f85659d2a4 + SSH-Copy-ID-Upstream: 1c124d9bfafdbe28a00b683367ebf5750ce12eb2 -commit f69319ad8ad1dd50f90bbcf5912e11cc8ed3e037 -Author: Darren Tucker -Date: Sat Jul 23 14:38:22 2022 +1000 +commit 801cda54c00e0f4e7d89345a90874c8d05dc233a +Author: Philip Hands +Date: Tue May 23 23:07:11 2023 +0200 - Convert "have_prog" function into "which". + drop whitespace - "which" and its behaviour is not standardized, so convert the existing - have_prog function into "which" so we can rely on it being available - and what its semantics are. Add a have_prog wrapper that maintains the - existing behaviour. + SSH-Copy-ID-Upstream: e604fae1cdee35c18055d35dcec530cf12ef00ad -commit ea7ecc2c3ae39fdf5c6ad97b7bc0b47a98847f43 -Author: Darren Tucker -Date: Sat Jul 23 14:36:38 2022 +1000 +commit 288482f53613f3e74544eb92deeb24f7c7f1f371 +Author: Philip Hands +Date: Tue May 23 20:52:13 2023 +0200 - Skip scp3 test if there's no scp on remote path. + make -x also apply to the target script - scp -3 ends up using the scp that's in the remote path and will fail if - one is not available. Based on a patch from rapier at psc.edu. - -commit c46f6fed419167c1671e4227459e108036c760f8 -Author: Damien Miller -Date: Wed Jul 20 13:39:14 2022 +1000 - - crank SSH_SK_VERSION_MAJOR in sk-dummy.so + SSH-Copy-ID-Upstream: 3c4214704f427bd0654adf9b0fc079253db21cf4 -commit f208e3b9ffb5ee76cf9c95df7ff967adc7f51c7d -Author: djm@openbsd.org -Date: Wed Jul 20 03:33:22 2022 +0000 +commit b79e7b88ed44f0e4339f0ff35c96c78a92175a8d +Author: Philip Hands +Date: Tue May 23 16:46:42 2023 +0200 - upstream: ssh-keygen: fix touch prompt, pin retries; - - part of GHPR329 from Pedro Martelletto + add -t option to specify the target path - OpenBSD-Commit-ID: 75d1005bd2ef8f29fa834c90d2684e73556fffe8 - -commit 8638a2ce7e90c8a51d9af3143404282126c524f8 -Author: djm@openbsd.org -Date: Wed Jul 20 03:31:42 2022 +0000 - - upstream: sk-usbhid: preserve error code returned by key_lookup() + Allow the default target path (.ssh/authorized_files) to be over-riden - it conveys useful information, such as the supplied pin being wrong. + This was inspired by this MR from Panagiotis Cheilaris - Part of GHPR329 from Pedro Martelletto + https://gitlab.com/phil_hands/ssh-copy-id/-/merge_requests/8 - OpenBSD-Commit-ID: c0647eb9290f793add363d81378439b273756c1b + SSH-Copy-ID-Upstream: a942a0e076874adb6d8b2f0fb76d6c7918190fcd -commit 9ab929ca2d820520327b41929372bcb9e261534c -Author: djm@openbsd.org -Date: Wed Jul 20 03:29:14 2022 +0000 +commit 914f4ad138714c471ba72fb6d5496b6235320edd +Author: Carlos Rodríguez Gili +Date: Tue Apr 20 19:23:57 2021 +0200 - upstream: when enrolling a resident key on a security token, check - - if a credential with matching application and user ID strings already exists. - if so, prompt the user for confirmation before overwriting the credential. - - patch from Pedro Martelletto via GHPR329 + Fix test error for /bin/sh on Solaris 10 and older - NB. cranks SSH_SK_VERSION_MAJOR, so any third-party FIDO middleware - implementations will need to adjust + On Solaris 10 and older targets /bin/sh is not POSIX-compliant. + Test -z `...` fails with error 'sh: test: argument expected'. + Using quotes around backticks fixes this and doesn't break + POSIX compatibility. - OpenBSD-Commit-ID: e45e9f1bf2b2f32d9850669e7a8dbd64acc5fca4 + SSH-Copy-ID-Upstream: 98394072a3f985b2650c1e8eab2fef84e38cc065 -commit 5bcfc788b38d5b64e4c347bdc04bd9a01bbc36da -Author: djm@openbsd.org -Date: Wed Jul 20 03:13:04 2022 +0000 +commit bd382dca316c721aed1e45edcf4c4e0f6374afb0 +Author: Jakub Jelen +Date: Tue Mar 2 21:34:05 2021 +0000 - upstream: pull passphrase reading and confirmation into a separate - - function so it can be used for FIDO2 PINs; no functional change + Remove outdated comment - OpenBSD-Commit-ID: bf34f76b8283cc1d3f54633e0d4f13613d87bb2f - -commit eb679e2959bdb15454eb94751930eb4c9110da94 -Author: Darren Tucker -Date: Fri Jul 15 21:31:48 2022 +1000 - - Move vmshutdown to first step. + The commit b068122 removed the code dropping the trailing colon, but the comment stayed leaving the code confusing for future readers - If a previous run on a physical runner has failed to clean up, the next - run will fail because it'll try to check out the code to a broken - directory mount. Make cleanup the first step. - -commit 46b91b70ff3cb9c147e2875ef5dc609fd64c0c96 -Author: Darren Tucker -Date: Fri Jul 15 20:25:27 2022 +1000 - - Rename bbone test target to ARM. + SSH-Copy-ID-Upstream: 930d39f238117cd53810240ec989d0356aa1c1f6 -commit 751d22cdeffed9fe921db78eedc32a29f9e80510 +commit bdcaf7939029433635d63aade8f9ac762aca2bbe Author: Darren Tucker -Date: Fri Jul 15 13:37:29 2022 +1000 +Date: Wed May 10 18:50:46 2023 +1000 - Add AUDIT_ARCH_PPC to supported seccomp arches. + Special case OpenWrt instead of Dropbear. - Patch from dries.deschout at dodeco.eu. - -commit a061792a6e8d235fc40a9b5d4c22a1762bb75a7b -Author: Darren Tucker -Date: Thu Jul 14 19:20:24 2022 +1000 - - Remove unintended changes. + OpenWrt overrides the location of authorized_keys for root. Currently we + assume that all Dropbear installations behave this way, which is not the + case. Check for OpenWrt and root user before using that location instead + of assuming that for all Dropbear servers. Prompted by Github PR#250. - I inadvertently included a couple of local changes with the OpenSSL - 3.0.4 change. Revert, anything that should be there will be committed - separately. + SSH-Copy-ID-Upstream: 0e1f5d443a9967483c33945793107ae3f3e4af2d -commit 527cb43fa1b4e55df661feabbac51b8e608b6519 -Author: Darren Tucker -Date: Thu Jul 14 11:22:08 2022 +1000 +commit cf84498f67abe93f813a296167b406a0db7b288e +Author: Philip Hands +Date: Thu May 18 18:20:55 2023 +0200 - Return ERANGE from getcwd() if buffer size is 1. + ssh-copy-id: add -x option (for debugging) - If getcwd() is supplied a buffer size of exactly 1 and a path of "/", it - could result in a nul byte being written out of array bounds. POSIX says - it should return ERANGE if the path will not fit in the available buffer - (with terminating nul). 1 byte cannot fit any possible path with its nul, - so immediately return ERANGE in that case. + This option causes the ssh-copy-id to run with set -x - OpenSSH never uses getcwd() with this buffer size, and all current - (and even quite old) platforms that we are currently known to work - on have a native getcwd() so this code is not used on those anyway. - Reported by Qualys, ok djm@ + SSH-Copy-ID-Upstream: a0ee367ea8c0a29c8b4515245e408d2d349e7844 -commit 36857fefd8849c4b0e877cfd9d1eb22f79b76650 -Author: Darren Tucker -Date: Thu Jul 14 10:02:35 2022 +1000 +commit b4a1efdcb88f03394c08e7f68ed4e11676830002 +Author: Philip Hands +Date: Thu May 18 17:14:41 2023 +0200 - Split README.platform into its own line. + update copyright notices - README.platform has general platform-specific information, having it - following text about FIDO2 on the same line could imply that it only - has information about FIDO2. + SSH-Copy-ID-Upstream: c284ed33b361814ea48ff68cbd01ca525b2bf117 -commit 00a496c6c14f2d41f2a9365714d494dd5f3aac9f -Author: Darren Tucker -Date: Thu Jul 14 09:56:01 2022 +1000 +commit fcd78e31cdd45a7e69ccfe6d8a3b1037dc1de290 +Author: djm@openbsd.org +Date: Wed May 24 23:01:06 2023 +0000 - Clarify README.md text. + upstream: fix AuthorizedPrincipalsCommand when AuthorizedKeysCommand - Clarify the text about the implications of building without OpenSSL, and - prefix the "configure --help" example command with a "./" so it's likely - to work as-is in more shells. From bz#3461. + appears previously in configuration. Reported by John Meyers in bz3574 ok + dtucker@ + + OpenBSD-Commit-ID: 1c92e4517284386703936e1d3abaa36cfacf1951 -commit f40b52f21fbc52eb513279168a49d3285c65256c -Author: Darren Tucker -Date: Tue Jul 12 19:48:44 2022 +1000 +commit 5ec5504f1d328d5bfa64280cd617c3efec4f78f3 +Author: dtucker@openbsd.org +Date: Wed May 10 10:04:20 2023 +0000 - Remove special casing of crypt(). + upstream: Remove unused prototypes for ssh1 RSA functions. - Configure goes to some lengths to pick crypt() from either libcrypt - or OpenSSL's libcrypto because they can more or less featureful (eg - supporting md5-style passwords). + From lengyijun via github PR#396. - OpenSSL removed its crypt() interface in 2002: - https://github.com/openssl/openssl/commit/69deec58 so these hijinks - should no longer be necessary. This also only links sshd with libcrypt - which is the only thing that needs it. ok djm@ + OpenBSD-Commit-ID: 379a5afa8b7a0f3cba0c8a9bcceb4e5e33a5c1ef -commit 76f4e48631d7b09fb243b47d7b393d100d3741b7 +commit fbf362b3891ae4b36052d1b39f37fc618b41c476 Author: Darren Tucker -Date: Wed Jul 13 13:17:47 2022 +1000 +Date: Tue May 9 19:26:56 2023 +1000 - Only refuse to use OpenSSL 3.0.4 on x86_64. - - The potential RCE only impacts x86_64, so only refuse to use it if we're - targetting a potentially impacted architecture. ok djm@ + main(void) to prevent unused variable warning. -commit e75bbc1d88491fa85e61b2cc8783d4bbd00cd131 +commit baf854c8bb0a6d0af5c696c801e631a48dabbaba Author: Darren Tucker -Date: Tue Jul 12 14:37:15 2022 +1000 +Date: Tue May 9 19:25:45 2023 +1000 - Capture stderr output from configure. + Remove warning pragma since clang doesn't like it. -commit d9eaea4bea6271bcee6a2b9428f1271faf2d033b +commit 5fbb7a1349fbbb48ccb1b8cafff2c1854370d87d Author: Darren Tucker -Date: Tue Jul 12 12:54:49 2022 +1000 +Date: Tue May 9 17:13:33 2023 +1000 - Refuse to use OpenSSL 3.0.4 due to potential RCE. - - OpenSSL has a potential RCE in its RSA implementation (CVE-2022-2274) - so refuse to use that specific version. + Suppress warning for snprintf truncation test. -commit fb2f3a61bf3d28fff285524535f7ffcd177c9235 +commit 47742c513e4e045ecc985c6483fc5c8b050acda2 Author: Darren Tucker -Date: Tue Jul 12 12:54:24 2022 +1000 +Date: Tue May 9 17:12:50 2023 +1000 - Move unset to before we set anything. + Update OpenSSL compat test for 3.x. -commit c483a5c0fb8e8b8915fad85c5f6113386a4341ca +commit 86ad25d455a2313126125540e61e0f9314283f88 Author: Darren Tucker -Date: Wed Jul 6 11:52:54 2022 +1000 +Date: Mon May 8 20:23:08 2023 +1000 - Test against openssl-3.0.5. + Add macos13 PAM test target. -commit 669a56bcfe73f8b985f2bba476ba834d55253acf +commit 77cca2c4b13bc6e5f389565583b6202b0d1bccc2 Author: Darren Tucker -Date: Tue Jul 5 18:35:53 2022 +1000 +Date: Mon May 8 20:14:46 2023 +1000 - Update sanitizer test targets: + Skip agent-peereid test on macos13. - - remove clang-sanitize-memory for now. It takes so long that the test - times out. - - add gcc sanitize-address and sanitize-undefined test targets. + sudo -S nobody doesn't work on the github runners (probably a + permission issue) so skip that test. -commit 48cc68b69118b3ce8d07fd4f82e00d58667d5379 +commit b356b8e91678ea295bcf44df5248c3fbf499fdcf Author: Darren Tucker -Date: Tue Jul 5 16:23:28 2022 +1000 +Date: Mon May 8 20:14:28 2023 +1000 - Add GCC address sanitizer build/test. + Include config.guess in debug output. -commit 55c60bdd39b82457e92efa77da8d16cfa6a49391 +commit b7afd8a4ecaca8afd3179b55e9db79c0ff210237 Author: Darren Tucker -Date: Tue Jul 5 12:02:33 2022 +1000 +Date: Mon May 8 20:12:59 2023 +1000 - Move sanitizer logs into regress for collection. + Handle OpenSSL >=3 ABI compatibility. + + Beyond OpenSSL 3.0, the ABI compatibility guarantees are wider (only + major must match instead of major and minor in earlier versions). + bz#3548, ok djm@ -commit 35ef2b3b6ef198f8574904a45780487ec2f17858 +commit 0e9e2663eb2c6e9c3e10d15d70418312ae67e542 Author: dtucker@openbsd.org -Date: Mon Jul 4 09:10:31 2022 +0000 +Date: Mon May 1 08:57:29 2023 +0000 - upstream: Add TEST_REGRESS_CACHE_DIR. - - If set, it is used to cache regress test names that have succeeded and - skip those on a re-run. + upstream: Import regenerated moduli. - OpenBSD-Regress-ID: a7570dd29a58df59f2cca647c3c2ec989b49f247 - -commit 7394ed80c4de8b228a43c8956cf2fa1b9c6b2622 -Author: Darren Tucker -Date: Sun Jul 3 21:46:44 2022 +1000 - - Add clang sanitizer tests. + OpenBSD-Commit-ID: 3d5f811cfcaed8cc4a97e1db49ac61bdf118113c -commit bfce0e66b6017a9bfab450b9dc7d4b16f90de817 +commit d9687f49682e1e93383fc15ab2018850b2ef38c3 Author: Darren Tucker -Date: Sun Jul 3 18:14:09 2022 +1000 +Date: Mon May 1 11:45:14 2023 +1000 - Skip all rlimit tests when sandboxing disabled. + Add macos-13 test target. - The rlimit tests can hang when being run with some compiler sanitizers - so skip all of them if sandbox=no. + Also flatten OS list for clarity. -commit 6208d611520f9ea94d5369f9da404b709930029d -Author: Darren Tucker -Date: Sun Jul 3 17:54:49 2022 +1000 +commit aacfd6767497b8fa6d41ecdd3f8e265d1e9ef1f6 +Author: djm@openbsd.org +Date: Sun Apr 30 22:54:22 2023 +0000 - Move checks for pollfd.fd and nfds_t. + upstream: adjust ftruncate() logic to handle servers that reorder + + requests. + + sftp/scp will ftruncate the destination file after a transfer completes, + to deal with the case where a longer destination file already existed. + We tracked the highest contiguous block transferred to deal with this + case, but our naive tracking doesn't deal with servers that reorder + requests - a misfeature strictly permitted by the protocol but seldom + implemented. + + Adjust the logic to ftruncate() at the highest absolute block received + when the transfer is successful. feedback deraadt@ ok markus@ - Move the checks for struct pollfd.fd and nfds_t to before the sandboxing - checks. This groups all the sandbox checks together so we can skip them - all when sandboxing is disabled. + prompted by https://github.com/openssh/openssh-portable/commit/9b733#commitcomment-110679778 + + OpenBSD-Commit-ID: 4af7fac75958ad8507b4fea58706f3ff0cfddb1b -commit 322964f8f2e9c321e77ebae1e4d2cd0ccc5c5a0b -Author: dtucker@openbsd.org -Date: Fri Jul 1 05:08:23 2022 +0000 +commit c8eb3941758615c8284a48fff47872db926da63c +Author: djm@openbsd.org +Date: Wed Apr 26 01:36:03 2023 +0000 - upstream: Remove leftover line. + upstream: Check for ProxyJump=none in CanonicalizeHostname logic. - Remove extra line leftover from merge conflict. ok djm@ + Previously ssh would incorrectly refuse to canonicalise the hostname + if ProxyJump was explicitly set to "none" when CanonicalizeHostname=yes + + bz3567; ok dtucker - OpenBSD-Commit-ID: 460e2290875d7ae64971a7e669c244b1d1c0ae2e + OpenBSD-Commit-ID: 80a58e43c3a32f97361282f756ec8d3f37989efd -commit 7ec81daad0e03a64e8d91c5590960c48c1a899a3 -Author: djm@openbsd.org -Date: Fri Jul 1 04:45:50 2022 +0000 +commit ac383f3a5c6f529a2e8a5bc44af79a08c7da294e +Author: jsg@openbsd.org +Date: Wed Apr 12 14:22:04 2023 +0000 - upstream: use consistent field names (s/char/byte) + upstream: remove duplicate signal.h include - in format description + OpenBSD-Commit-ID: 30c0a34d74d91ddd0e6992525da70d3293392f70 + +commit 740dafa20f3f3d325f6f5d44e990b8c8a6d3d816 +Author: jsg@openbsd.org +Date: Wed Apr 12 08:53:54 2023 +0000 + + upstream: fix double words ok dtucker@ - OpenBSD-Commit-ID: 3de33572733ee7fcfd7db33d37db23d2280254f0 + OpenBSD-Commit-ID: 44d3223902fbce5276422bdc8063ab72a4078489 + +commit 6452f89577ec4f22440c31b8e19b061d1a7c4b2a +Author: Darren Tucker +Date: Tue Apr 11 16:49:19 2023 +1000 + + Test against LibreSSL 3.7.2. diff --git a/INSTALL b/INSTALL index f99d1e2a809..3ad1659f36f 100644 --- a/INSTALL +++ b/INSTALL @@ -41,15 +41,17 @@ direct support of /dev/random, or failing that, either prngd or egd. PRNGD: If your system lacks kernel-based random collection, the use of Lutz -Jaenicke's PRNGd is recommended. It requires that libcrypto be configured -to support it. +Jaenicke's PRNGd is recommended. If you are using libcrypto it requires +that the libcrypto is configured to support it. If you are building +--without-openssl then the --with-prngd-socket option must match the +socket provided by prngd. http://prngd.sourceforge.net/ EGD: The Entropy Gathering Daemon (EGD) supports the same interface as prngd. -It also supported only if libcrypto is configured to support it. +The same caveats about configuration for prngd also apply. http://egd.sourceforge.net/ @@ -94,8 +96,8 @@ http://nlnetlabs.nl/projects/ldns/ Autoconf: If you modify configure.ac or configure doesn't exist (eg if you checked -the code out of git yourself) then you will need autoconf-2.69 and -automake-1.16.1 to rebuild the automatically generated files by running +the main git branch) then you will need autoconf-2.69 and automake-1.16.1 +or newer to rebuild the automatically generated files by running "autoreconf". Earlier versions may also work but this is not guaranteed. http://www.gnu.org/software/autoconf/ diff --git a/LICENCE b/LICENCE index 4b0db548a1b..aeb3017e76c 100644 --- a/LICENCE +++ b/LICENCE @@ -367,5 +367,46 @@ OpenSSH contains no GPL code. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. + The replacement base64 implementation has the following MIT-style + licenses: + + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM 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. + + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + ------ $OpenBSD: LICENCE,v 1.20 2017/04/30 23:26:16 djm Exp $ diff --git a/Makefile.in b/Makefile.in index e1b77ebc649..4617cebcd5e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,13 +18,13 @@ top_srcdir=@top_srcdir@ abs_top_srcdir=@abs_top_srcdir@ abs_top_builddir=@abs_top_builddir@ -DESTDIR= VPATH=@srcdir@ SSH_PROGRAM=@bindir@/ssh ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass SFTP_SERVER=$(libexecdir)/sftp-server SSH_KEYSIGN=$(libexecdir)/ssh-keysign SSHD_SESSION=$(libexecdir)/sshd-session +SSHD_AUTH=$(libexecdir)/sshd-auth SSH_PKCS11_HELPER=$(libexecdir)/ssh-pkcs11-helper SSH_SK_HELPER=$(libexecdir)/ssh-sk-helper PRIVSEP_PATH=@PRIVSEP_PATH@ @@ -32,6 +32,7 @@ SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ STRIP_OPT=@STRIP_OPT@ TEST_SHELL=@TEST_SHELL@ BUILDDIR=@abs_top_builddir@ +SK_STANDALONE=@SK_STANDALONE@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \ -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \ @@ -39,6 +40,7 @@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \ -D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \ -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \ -D_PATH_SSHD_SESSION=\"$(SSHD_SESSION)\" \ + -D_PATH_SSHD_AUTH=\"$(SSHD_AUTH)\" \ -D_PATH_SSH_PKCS11_HELPER=\"$(SSH_PKCS11_HELPER)\" \ -D_PATH_SSH_SK_HELPER=\"$(SSH_SK_HELPER)\" \ -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ @@ -57,6 +59,7 @@ GSSLIBS=@GSSLIBS@ SSHDLIBS=@SSHDLIBS@ LIBEDIT=@LIBEDIT@ LIBFIDO2=@LIBFIDO2@ +LIBWTMPDB=@LIBWTMPDB@ AR=@AR@ AWK=@AWK@ RANLIB=@RANLIB@ @@ -71,7 +74,7 @@ MKDIR_P=@MKDIR_P@ .SUFFIXES: .lo -TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) +TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) $(SK_STANDALONE) XMSS_OBJS=\ ssh-xmss.o \ @@ -111,7 +114,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ hmac.o ed25519.o hash.o \ kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexgexc.o kexgexs.o \ - kexsntrup761x25519.o sntrup761.o kexgen.o \ + kexsntrup761x25519.o kexmlkem768x25519.o sntrup761.o kexgen.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ sshbuf-io.o @@ -137,9 +140,22 @@ SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ sftp-server.o sftp-common.o \ - sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ - sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-pledge.o \ - sandbox-solaris.o uidswap.o $(SKOBJS) + uidswap.o platform-listen.o $(SKOBJS) + +SSHD_AUTH_OBJS=sshd-auth.o \ + auth2-methods.o \ + auth-rhosts.o auth-passwd.o sshpty.o sshlogin.o servconf.o \ + serverloop.o auth.o auth2.o auth-options.o session.o auth2-chall.o \ + groupaccess.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ + auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o \ + monitor_wrap.o auth-krb5.o \ + audit.o audit-bsm.o audit-linux.o platform.o \ + loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ + sandbox-null.o sandbox-rlimit.o sandbox-darwin.o \ + sandbox-seccomp-filter.o sandbox-capsicum.o sandbox-solaris.o \ + sftp-server.o sftp-common.o \ + uidswap.o $(SKOBJS) SFTP_CLIENT_OBJS=sftp-common.o sftp-client.o sftp-glob.o @@ -218,7 +234,10 @@ sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS) sshd-session$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_SESSION_OBJS) - $(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) + $(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB) + +sshd-auth$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_AUTH_OBJS) + $(LD) -o $@ $(SSHD_AUTH_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB) scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS) $(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -254,6 +273,16 @@ sftp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SFTP_OBJS) logintest: logintest.o $(LIBCOMPAT) libssh.a loginrec.o $(LD) -o $@ logintest.o $(LDFLAGS) loginrec.o -lopenbsd-compat -lssh $(LIBS) +# compile libssh objects with -fPIC for use in the sk_libfido2 shared library +LIBSSH_PIC_OBJS=$(LIBSSH_OBJS:.o=.lo) +libssh-pic.a: $(LIBSSH_PIC_OBJS) + $(AR) rv $@ $(LIBSSH_PIC_OBJS) + $(RANLIB) $@ + +$(SK_STANDALONE): $(srcdir)/sk-usbhid.c $(LIBCOMPAT) libssh-pic.a + $(CC) -o $@ -shared $(CFLAGS_NOPIE) $(CPPFLAGS) -DSK_STANDALONE $(PICFLAG) $(srcdir)/sk-usbhid.c \ + libssh-pic.a $(LDFLAGS_NOPIE) -lopenbsd-compat $(LIBS) $(LIBFIDO2) $(CHANNELLIBS) + $(MANPAGES): $(MANPAGES_IN) if test "$(MANTYPE)" = "cat"; then \ manpage=$(srcdir)/`echo $@ | sed 's/\.[1-9]\.out$$/\.0/'`; \ @@ -267,7 +296,7 @@ $(MANPAGES): $(MANPAGES_IN) $(FIXPATHSCMD) $${manpage} | $(FIXALGORITHMSCMD) > $@; \ fi -$(CONFIGFILES): $(CONFIGFILES_IN) +$(CONFIGFILES): $(CONFIGFILES_IN) Makefile conffile=`echo $@ | sed 's/.out$$//'`; \ $(FIXPATHSCMD) $(srcdir)/$${conffile} > $@ @@ -306,7 +335,8 @@ clean: regressclean rm -f regress/unittests/utf8/test_utf8$(EXEEXT) rm -f regress/misc/sk-dummy/*.o rm -f regress/misc/sk-dummy/*.lo - rm -f regress/misc/sk-dummy/sk-dummy.so + rm -f regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT) + rm -f regress/misc/ssh-verify-attestation/*.o (cd openbsd-compat && $(MAKE) clean) distclean: regressclean @@ -344,6 +374,8 @@ distclean: regressclean rm -f regress/misc/sk-dummy/*.o rm -f regress/misc/sk-dummy/*.lo rm -f regress/misc/sk-dummy/sk-dummy.so + rm -f regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT) + rm -f regress/misc/ssh-verify-attestation/*.o (cd openbsd-compat && $(MAKE) distclean) if test -d pkg ; then \ rm -fr pkg ; \ @@ -411,6 +443,7 @@ install-files: $(INSTALL) -m 0755 $(STRIP_OPT) ssh-keyscan$(EXEEXT) $(DESTDIR)$(bindir)/ssh-keyscan$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sshd$(EXEEXT) $(DESTDIR)$(sbindir)/sshd$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) sshd-session$(EXEEXT) $(DESTDIR)$(SSHD_SESSION)$(EXEEXT) + $(INSTALL) -m 0755 $(STRIP_OPT) sshd-auth$(EXEEXT) $(DESTDIR)$(SSHD_AUTH)$(EXEEXT) $(INSTALL) -m 4711 $(STRIP_OPT) ssh-keysign$(EXEEXT) $(DESTDIR)$(SSH_KEYSIGN)$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) ssh-pkcs11-helper$(EXEEXT) $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT) $(INSTALL) -m 0755 $(STRIP_OPT) ssh-sk-helper$(EXEEXT) $(DESTDIR)$(SSH_SK_HELPER)$(EXEEXT) @@ -519,6 +552,7 @@ regress-prep: $(MKDIR_P) `pwd`/regress/unittests/sshsig $(MKDIR_P) `pwd`/regress/unittests/utf8 $(MKDIR_P) `pwd`/regress/misc/sk-dummy + $(MKDIR_P) `pwd`/regress/misc/ssh-verify-attestation [ -f `pwd`/regress/Makefile ] || \ ln -s `cd $(srcdir) && pwd`/regress/Makefile `pwd`/regress/Makefile @@ -705,6 +739,16 @@ regress/misc/sk-dummy/sk-dummy.so: $(SK_DUMMY_OBJS) $(CC) $(CFLAGS) $(CPPFLAGS) $(PICFLAG) -shared -o $@ $(SK_DUMMY_OBJS) \ -L. -Lopenbsd-compat -lopenbsd-compat $(LDFLAGS_NOPIE) $(TESTLIBS) +SSH_VERIFY_ATTESTATION_OBJS=\ + regress/misc/ssh-verify-attestation/ssh-verify-attestation.o \ + $(SKOBJS) + +ssh-verify-attestation: regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT) + +regress/misc/ssh-verify-attestation/ssh-verify-attestation$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSH_VERIFY_ATTESTATION_OBJS) + $(LD) -o $@ $(SSH_VERIFY_ATTESTATION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(CHANNELLIBS) $(LIBFIDO2) + + regress-binaries: regress-prep $(LIBCOMPAT) \ regress/modpipe$(EXEEXT) \ regress/timestamp$(EXEEXT) \ @@ -738,6 +782,8 @@ unit: regress-unit-binaries OBJ="$(BUILDDIR)/regress" \ $@ && echo $@ tests passed +TEST_SSH_SSHD="$(BUILDDIR)/sshd" + interop-tests t-exec file-tests extra-tests: regress-prep regress-binaries $(TARGETS) cd $(srcdir)/regress || exit $$?; \ EGREP='@EGREP@' \ @@ -752,8 +798,9 @@ interop-tests t-exec file-tests extra-tests: regress-prep regress-binaries $(TAR TEST_MALLOC_OPTIONS="@TEST_MALLOC_OPTIONS@" \ TEST_SSH_SCP="$(BUILDDIR)/scp" \ TEST_SSH_SSH="$(BUILDDIR)/ssh" \ - TEST_SSH_SSHD="$(BUILDDIR)/sshd" \ + TEST_SSH_SSHD="$(TEST_SSH_SSHD)" \ TEST_SSH_SSHD_SESSION="$(BUILDDIR)/sshd-session" \ + TEST_SSH_SSHD_AUTH="$(BUILDDIR)/sshd-auth" \ TEST_SSH_SSHAGENT="$(BUILDDIR)/ssh-agent" \ TEST_SSH_SSHADD="$(BUILDDIR)/ssh-add" \ TEST_SSH_SSHKEYGEN="$(BUILDDIR)/ssh-keygen" \ diff --git a/PROTOCOL.agent b/PROTOCOL.agent index 9ae16bf2bbc..b6e14262d0f 100644 --- a/PROTOCOL.agent +++ b/PROTOCOL.agent @@ -1,5 +1,5 @@ The SSH agent protocol is described in -https://tools.ietf.org/html/draft-miller-ssh-agent +https://datatracker.ietf.org/doc/draft-ietf-sshm-ssh-agent/ This file documents OpenSSH's extensions to the agent protocol. @@ -115,4 +115,4 @@ A SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED will return SSH_AGENT_SUCCESS if any key (plain private or certificate) was successfully loaded, or SSH_AGENT_FAILURE if no key was loaded. -$OpenBSD: PROTOCOL.agent,v 1.23 2024/04/30 05:45:56 djm Exp $ +$OpenBSD: PROTOCOL.agent,v 1.24 2024/11/27 13:27:34 djm Exp $ diff --git a/PROTOCOL.certkeys b/PROTOCOL.certkeys index 68622e60743..0a212c635c5 100644 --- a/PROTOCOL.certkeys +++ b/PROTOCOL.certkeys @@ -231,10 +231,15 @@ is a sequence of zero or more tuples: Options must be lexically ordered by "name" if they appear in the sequence. Each named option may only appear once in a certificate. -The name field identifies the option and the data field encodes -option-specific information (see below). All options are -"critical"; if an implementation does not recognise a option, -then the validating party should refuse to accept the certificate. +The name field identifies the option. The data field contains +option-specific information encoded as zero or more values inside +the string. I.e. an empty data field would be encoded as a zero- +length string (00 00 00 00), and data field that holds a single +string value "a" would be encoded as (00 00 00 05 00 00 00 01 65). + +All options are "critical"; if an implementation does not recognise +a option, then the validating party should refuse to accept the +certificate. Custom options should append the originating author or organisation's domain name to the option name, e.g. "my-option@example.com". @@ -318,4 +323,4 @@ permit-user-rc empty Flag indicating that execution of of this script will not be permitted if this option is not present. -$OpenBSD: PROTOCOL.certkeys,v 1.19 2021/06/05 13:47:00 naddy Exp $ +$OpenBSD: PROTOCOL.certkeys,v 1.20 2024/12/06 16:02:12 djm Exp $ diff --git a/README b/README index 2388ebbfba1..0ea77da1c1d 100644 --- a/README +++ b/README @@ -1,19 +1,19 @@ -See https://www.openssh.com/releasenotes.html#9.8p1 for the release +See https://www.openssh.com/releasenotes.html#10.0p1 for the release notes. Please read https://www.openssh.com/report.html for bug reporting -instructions and note that we do not use Github for bug reporting or -patch/pull-request management. +instructions and note that we do not use Github for bug reporting. This is the port of OpenBSD's excellent OpenSSH[0] to Linux and other Unices. OpenSSH is based on the last free version of Tatu Ylonen's sample -implementation with all patent-encumbered algorithms removed (to -external libraries), all known security bugs fixed, new features -reintroduced and many other clean-ups. OpenSSH has been created by -Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt, -and Dug Song. It has a homepage at https://www.openssh.com/ +implementation with all patent-encumbered algorithms removed (to external +libraries), all known security bugs fixed, new features reintroduced and +many other clean-ups. OpenSSH was created by Aaron Campbell, Bob Beck, +Markus Friedl, Niels Provos, Theo de Raadt, and Dug Song, and has been +developed and maintained by Andre Lucas, Ben Lindstom, Damien Miller, +Darren Tucker and Tim Rice. It has a homepage at https://www.openssh.com/ This port consists of the re-introduction of autoconf support, PAM support, EGD/PRNGD support and replacements for OpenBSD library @@ -23,10 +23,6 @@ FreeBSD, NetBSD, OpenBSD, OpenServer, Solaris and UnixWare. This version actively tracks changes in the OpenBSD CVS repository. -The PAM support is now more functional than the popular packages of -commercial ssh-1.2.x. It checks "account" and "session" modules for -all logins, not just when using password authentication. - There is now several mailing lists for this port of OpenSSH. Please refer to https://www.openssh.com/list.html for details on how to join. diff --git a/README.md b/README.md index 9431b0ffdd8..2ad6471386e 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ In addition, certain platforms and build-time options may require additional dep ### Building a release -Releases include a pre-built copy of the ``configure`` script and may be built using: +Release tarballs and release branches in git include a pre-built copy of the ``configure`` script and may be built using: ``` tar zxvf openssh-X.YpZ.tar.gz @@ -54,7 +54,7 @@ See the [Build-time Customisation](#build-time-customisation) section below for ### Building from git -If building from git, you'll need [autoconf](https://www.gnu.org/software/autoconf/) installed to build the ``configure`` script. The following commands will check out and build portable OpenSSH from git: +If building from the git master branch, you'll need [autoconf](https://www.gnu.org/software/autoconf/) installed to build the ``configure`` script. The following commands will check out and build portable OpenSSH from git: ``` git clone https://github.com/openssh/openssh-portable # or https://anongit.mindrot.org/openssh.git diff --git a/addr.c b/addr.c index 0e7cb1df39f..e207287c1f5 100644 --- a/addr.c +++ b/addr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: addr.c,v 1.8 2024/04/02 09:29:31 deraadt Exp $ */ +/* $OpenBSD: addr.c,v 1.9 2024/10/18 04:30:09 djm Exp $ */ /* * Copyright (c) 2004-2008 Damien Miller @@ -33,7 +33,7 @@ #define _SA(x) ((struct sockaddr *)(x)) -int +static int addr_unicast_masklen(int af) { switch (af) { @@ -59,7 +59,7 @@ masklen_valid(int af, u_int masklen) } } -int +static int addr_xaddr_to_sa(const struct xaddr *xa, struct sockaddr *sa, socklen_t *len, u_int16_t port) { @@ -138,7 +138,7 @@ addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa) return 0; } -int +static int addr_invert(struct xaddr *n) { int i; @@ -193,7 +193,7 @@ addr_netmask(int af, u_int l, struct xaddr *n) } } -int +static int addr_hostmask(int af, u_int l, struct xaddr *n) { if (addr_netmask(af, l, n) == -1 || addr_invert(n) == -1) @@ -228,7 +228,7 @@ addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b) } } -int +static int addr_or(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b) { int i; @@ -283,7 +283,7 @@ addr_cmp(const struct xaddr *a, const struct xaddr *b) } } -int +static int addr_is_all0s(const struct xaddr *a) { int i; @@ -330,7 +330,7 @@ addr_increment(struct xaddr *a) * Returns 0 if host portion of address is all-zeros, * -1 if not all zeros or on failure. */ -int +static int addr_host_is_all0s(const struct xaddr *a, u_int masklen) { struct xaddr tmp_addr, tmp_mask, tmp_result; @@ -344,7 +344,7 @@ addr_host_is_all0s(const struct xaddr *a, u_int masklen) } #if 0 -int +static int addr_host_to_all0s(struct xaddr *a, u_int masklen) { struct xaddr tmp_mask; @@ -402,7 +402,8 @@ addr_pton(const char *p, struct xaddr *n) return 0; } -int +#if 0 +static int addr_sa_pton(const char *h, const char *s, struct sockaddr *sa, socklen_t slen) { struct addrinfo hints, *ai; @@ -432,6 +433,7 @@ addr_sa_pton(const char *h, const char *s, struct sockaddr *sa, socklen_t slen) freeaddrinfo(ai); return 0; } +#endif int addr_ntop(const struct xaddr *n, char *p, size_t len) diff --git a/addr.h b/addr.h index 180e9fdc644..29438dfecf2 100644 --- a/addr.h +++ b/addr.h @@ -39,24 +39,13 @@ struct xaddr { #define addr32 xa.addr32 }; -int addr_unicast_masklen(int af); -int addr_xaddr_to_sa(const struct xaddr *xa, struct sockaddr *sa, - socklen_t *len, u_int16_t port); int addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa); int addr_netmask(int af, u_int l, struct xaddr *n); -int addr_hostmask(int af, u_int l, struct xaddr *n); -int addr_invert(struct xaddr *n); int addr_pton(const char *p, struct xaddr *n); -int addr_sa_pton(const char *h, const char *s, struct sockaddr *sa, - socklen_t slen); int addr_pton_cidr(const char *p, struct xaddr *n, u_int *l); int addr_ntop(const struct xaddr *n, char *p, size_t len); int addr_and(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b); -int addr_or(struct xaddr *dst, const struct xaddr *a, const struct xaddr *b); int addr_cmp(const struct xaddr *a, const struct xaddr *b); -int addr_is_all0s(const struct xaddr *n); -int addr_host_is_all0s(const struct xaddr *n, u_int masklen); -int addr_host_to_all0s(struct xaddr *a, u_int masklen); int addr_host_to_all1s(struct xaddr *a, u_int masklen); int addr_netmatch(const struct xaddr *host, const struct xaddr *net, u_int masklen); diff --git a/auth.c b/auth.c index ec3090fe2b1..d6608e740f3 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.161 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: auth.c,v 1.162 2024/09/15 01:18:26 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -485,6 +485,9 @@ getpwnamallow(struct ssh *ssh, const char *user) { #ifdef HAVE_LOGIN_CAP extern login_cap_t *lc; +#ifdef HAVE_AUTH_HOSTOK + const char *from_host, *from_ip; +#endif #ifdef BSD_AUTH auth_session_t *as; #endif @@ -501,8 +504,10 @@ getpwnamallow(struct ssh *ssh, const char *user) */ pw = getpwnam(user); ci->user = pw? xstrdup(pw->pw_name): user; + ci->user_invalid = (pw == NULL); #else ci->user = user; + ci->user_invalid = getpwnam(user) == NULL; #endif // WINDOWS parse_server_match_config(&options, &includes, ci); log_change_level(options.log_level); @@ -540,6 +545,21 @@ getpwnamallow(struct ssh *ssh, const char *user) debug("unable to get login class: %s", user); return (NULL); } +#ifdef HAVE_AUTH_HOSTOK + from_host = auth_get_canonical_hostname(ssh, options.use_dns); + from_ip = ssh_remote_ipaddr(ssh); + if (!auth_hostok(lc, from_host, from_ip)) { + debug("Denied connection for %.200s from %.200s [%.200s].", + pw->pw_name, from_host, from_ip); + return (NULL); + } +#endif /* HAVE_AUTH_HOSTOK */ +#ifdef HAVE_AUTH_TIMEOK + if (!auth_timeok(lc, time(NULL))) { + debug("LOGIN %.200s REFUSED (TIME)", pw->pw_name); + return (NULL); + } +#endif /* HAVE_AUTH_TIMEOK */ #ifdef BSD_AUTH if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 || auth_approval(as, lc, pw->pw_name, "ssh") <= 0) { diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 6cda4c35c3d..f55c8f18624 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.120 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.122 2024/12/12 09:09:09 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -41,6 +41,11 @@ #include #include #include +#ifdef USE_SYSTEM_GLOB +# include +#else +# include "openbsd-compat/glob.h" +#endif #include "xmalloc.h" #include "ssh.h" @@ -319,20 +324,51 @@ match_principals_file(struct passwd *pw, char *file, struct sshkey_cert *cert, struct sshauthopt **authoptsp) { FILE *f; - int success; + int r, success = 0; + size_t i; + glob_t gl; + struct sshauthopt *opts = NULL; if (authoptsp != NULL) *authoptsp = NULL; temporarily_use_uid(pw); - debug("trying authorized principals file %s", file); - if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) { - restore_uid(); + r = glob(file, 0, NULL, &gl); + restore_uid(); + if (r != 0) { + if (r != GLOB_NOMATCH) { + logit_f("glob \"%s\" failed", file); + } return 0; + } else if (gl.gl_pathc > INT_MAX) { + fatal_f("too many glob results for \"%s\"", file); + } else if (gl.gl_pathc > 1) { + debug2_f("glob \"%s\" returned %zu matches", file, + gl.gl_pathc); + } + for (i = 0; !success && i < gl.gl_pathc; i++) { + temporarily_use_uid(pw); + debug("trying authorized principals file %s", file); + if ((f = auth_openprincipals(gl.gl_pathv[i], pw, + options.strict_modes)) == NULL) { + restore_uid(); + continue; + } + success = auth_process_principals(f, gl.gl_pathv[i], + cert, &opts); + fclose(f); + restore_uid(); + if (!success) { + sshauthopt_free(opts); + opts = NULL; + } } - success = auth_process_principals(f, file, cert, authoptsp); - fclose(f); - restore_uid(); + globfree(&gl); + if (success && authoptsp != NULL) { + *authoptsp = opts; + opts = NULL; + } + sshauthopt_free(opts); return success; } @@ -753,8 +789,8 @@ int user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, int auth_attempt, struct sshauthopt **authoptsp) { - u_int success = 0, i; - char *file, *conn_id; + u_int success = 0, i, j; + char *file = NULL, *conn_id; struct sshauthopt *opts = NULL; const char *rdomain, *remote_ip, *remote_host; @@ -776,17 +812,43 @@ user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, remote_ip, ssh_remote_port(ssh)); for (i = 0; !success && i < options.num_authkeys_files; i++) { + int r; + glob_t gl; + if (strcasecmp(options.authorized_keys_files[i], "none") == 0) continue; file = expand_authorized_keys( options.authorized_keys_files[i], pw); - success = user_key_allowed2(pw, key, file, - remote_ip, remote_host, &opts); - free(file); - if (!success) { - sshauthopt_free(opts); - opts = NULL; + temporarily_use_uid(pw); +#ifdef WINDOWS + convertToForwardslash(file); +#endif // WINDOWS + r = glob(file, 0, NULL, &gl); + restore_uid(); + if (r != 0) { + if (r != GLOB_NOMATCH) { + logit_f("glob \"%s\" failed", file); + } + free(file); + file = NULL; + continue; + } else if (gl.gl_pathc > INT_MAX) { + fatal_f("too many glob results for \"%s\"", file); + } else if (gl.gl_pathc > 1) { + debug2_f("glob \"%s\" returned %zu matches", file, + gl.gl_pathc); } + for (j = 0; !success && j < gl.gl_pathc; j++) { + success = user_key_allowed2(pw, key, gl.gl_pathv[j], + remote_ip, remote_host, &opts); + if (!success) { + sshauthopt_free(opts); + opts = NULL; + } + } + free(file); + file = NULL; + globfree(&gl); } if (success) goto out; diff --git a/auth2.c b/auth2.c index 4fc139e8b07..a0f6ca7ed83 100644 --- a/auth2.c +++ b/auth2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.169 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: auth2.c,v 1.170 2025/01/17 00:09:41 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -241,7 +241,7 @@ user_specific_delay(const char *user) /* 0-4.2 ms of delay */ delay = (double)PEEK_U32(hash) / 1000 / 1000 / 1000 / 1000; freezero(hash, len); - debug3_f("user specific delay %0.3lfms", delay/1000); + debug3_f("user specific delay %0.3lfms", delay*1000); return MIN_FAIL_DELAY_SECONDS + delay; } diff --git a/authfile.c b/authfile.c index 31ea500cfc4..151fc21334c 100644 --- a/authfile.c +++ b/authfile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: authfile.c,v 1.144 2023/03/14 07:26:25 dtucker Exp $ */ +/* $OpenBSD: authfile.c,v 1.145 2024/09/22 12:56:21 jsg Exp $ */ /* * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. * @@ -50,8 +50,6 @@ #include "krl.h" #include "sshfileperm.h" -#define MAX_KEY_FILE_SIZE (1024 * 1024) - /* Save a key blob to a file */ static int sshkey_save_private_blob(struct sshbuf *keybuf, const char *filename) diff --git a/buildpkg.sh.in b/buildpkg.sh.in index 15555cd7ed7..9a3bd1d227c 100644 --- a/buildpkg.sh.in +++ b/buildpkg.sh.in @@ -34,7 +34,7 @@ SSHDGID=67 # Default privsep gid #USR_LOCAL_IS_SYMLINK=yes # System V init run levels SYSVINITSTART=S98 -SYSVINITSTOPT=K30 +SYSVINITSTOP=K30 # We will source these if they exist POST_MAKE_INSTALL_FIXES=./pkg-post-make-install-fixes.sh POST_PROTOTYPE_EDITS=./pkg-post-prototype-edit.sh @@ -270,13 +270,13 @@ else cat > space << _EOF # extra space required by start/stop links added by installf # in postinstall -$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1 +$TEST_DIR/etc/rc0.d/${SYSVINITSTOP}${SYSVINIT_NAME} 0 1 $TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME} 0 1 _EOF [ "$RC1_D" = no ] || \ - echo "$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space + echo "$TEST_DIR/etc/rc1.d/${SYSVINITSTOP}${SYSVINIT_NAME} 0 1" >> space [ "$RCS_D" = yes ] && \ - echo "$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME} 0 1" >> space + echo "$TEST_DIR/etc/rcS.d/${SYSVINITSTOP}${SYSVINIT_NAME} 0 1" >> space fi ## Build preinstall file @@ -338,17 +338,17 @@ else if [ "\${USE_SYM_LINKS}" = yes ] then [ "$RCS_D" = yes ] && \\ - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOP}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOP}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s [ "$RC1_D" = no ] || \\ - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOP}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=../init.d/${SYSVINIT_NAME} s else [ "$RCS_D" = yes ] && \\ - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rcS.d/${SYSVINITSTOP}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc0.d/${SYSVINITSTOP}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l [ "$RC1_D" = no ] || \\ - installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOPT}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l + installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc1.d/${SYSVINITSTOP}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l installf ${PKGNAME} \${PKG_INSTALL_ROOT}$TEST_DIR/etc/rc2.d/${SYSVINITSTART}${SYSVINIT_NAME}=\${PKG_INSTALL_ROOT}$TEST_DIR/etc/init.d/${SYSVINIT_NAME} l fi fi diff --git a/channels.c b/channels.c index fe30487d417..6caab482710 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.438 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: channels.c,v 1.442 2024/12/05 06:49:26 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -94,6 +94,8 @@ #define NUM_SOCKS 10 /* -- X11 forwarding */ +/* X11 port for display :0 */ +#define X11_BASE_PORT 6000 /* Maximum number of fake X11 displays to try. */ #define MAX_DISPLAYS 1000 @@ -1016,14 +1018,16 @@ channel_format_status(const Channel *c) { char *ret = NULL; - xasprintf(&ret, "t%d [%s] %s%u i%u/%zu o%u/%zu e[%s]/%zu " - "fd %d/%d/%d sock %d cc %d io 0x%02x/0x%02x", + xasprintf(&ret, "t%d [%s] %s%u %s%u i%u/%zu o%u/%zu e[%s]/%zu " + "fd %d/%d/%d sock %d cc %d %s%u io 0x%02x/0x%02x", c->type, c->xctype != NULL ? c->xctype : c->ctype, c->have_remote_id ? "r" : "nr", c->remote_id, + c->mux_ctx != NULL ? "m" : "nm", c->mux_downstream_id, c->istate, sshbuf_len(c->input), c->ostate, sshbuf_len(c->output), channel_format_extended_usage(c), sshbuf_len(c->extended), c->rfd, c->wfd, c->efd, c->sock, c->ctl_chan, + c->have_ctl_child_id ? "c" : "nc", c->ctl_child_id, c->io_want, c->io_ready); return ret; } @@ -5005,19 +5009,19 @@ x11_create_display_inet(struct ssh *ssh, int x11_display_offset, u_int *display_numberp, int **chanids) { Channel *nc = NULL; - int display_number, sock; - u_short port; + int display_number, sock, port; struct addrinfo hints, *ai, *aitop; char strport[NI_MAXSERV]; int gaierr, n, num_socks = 0, socks[NUM_SOCKS]; - if (chanids == NULL) + if (chanids == NULL || x11_display_offset < 0 || + x11_display_offset > UINT16_MAX - X11_BASE_PORT - MAX_DISPLAYS) return -1; for (display_number = x11_display_offset; display_number < MAX_DISPLAYS; display_number++) { - port = 6000 + display_number; + port = X11_BASE_PORT + display_number; memset(&hints, 0, sizeof(hints)); hints.ai_family = ssh->chanctxt->IPv4or6; hints.ai_flags = x11_use_localhost ? 0: AI_PASSIVE; @@ -5233,7 +5237,8 @@ x11_connect_display(struct ssh *ssh) * buf now contains the host name. But first we parse the * display number. */ - if (sscanf(cp + 1, "%u", &display_number) != 1) { + if (sscanf(cp + 1, "%u", &display_number) != 1 || + display_number > UINT16_MAX - X11_BASE_PORT) { error("Could not parse display number from DISPLAY: %.100s", display); return -1; @@ -5243,7 +5248,7 @@ x11_connect_display(struct ssh *ssh) memset(&hints, 0, sizeof(hints)); hints.ai_family = ssh->chanctxt->IPv4or6; hints.ai_socktype = SOCK_STREAM; - snprintf(strport, sizeof strport, "%u", 6000 + display_number); + snprintf(strport, sizeof strport, "%u", X11_BASE_PORT + display_number); if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) { error("%.100s: unknown host. (%s)", buf, ssh_gai_strerror(gaierr)); @@ -5259,7 +5264,7 @@ x11_connect_display(struct ssh *ssh) /* Connect it to the display. */ if (connect(sock, ai->ai_addr, ai->ai_addrlen) == -1) { debug2("connect %.100s port %u: %.100s", buf, - 6000 + display_number, strerror(errno)); + X11_BASE_PORT + display_number, strerror(errno)); close(sock); continue; } @@ -5269,7 +5274,7 @@ x11_connect_display(struct ssh *ssh) freeaddrinfo(aitop); if (!ai) { error("connect %.100s port %u: %.100s", buf, - 6000 + display_number, strerror(errno)); + X11_BASE_PORT + display_number, strerror(errno)); return -1; } set_nodelay(sock); @@ -5343,3 +5348,22 @@ x11_request_forwarding_with_spoofing(struct ssh *ssh, int client_session_id, fatal_fr(r, "send x11-req"); free(new_data); } + +/* + * Returns whether an x11 channel was used recently (less than a second ago) + */ +int +x11_channel_used_recently(struct ssh *ssh) { + u_int i; + Channel *c; + time_t lastused = 0; + + for (i = 0; i < ssh->chanctxt->channels_alloc; i++) { + c = ssh->chanctxt->channels[i]; + if (c == NULL || c->ctype == NULL || c->lastused == 0 || + strcmp(c->ctype, "x11-connection") != 0) + continue; + lastused = c->lastused; + } + return lastused != 0 && monotime() > lastused + 1; +} diff --git a/channels.h b/channels.h index fdea9f574d6..134528d59c7 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.156 2024/05/23 23:47:16 jsg Exp $ */ +/* $OpenBSD: channels.h,v 1.158 2024/10/13 22:20:06 djm Exp $ */ /* * Author: Tatu Ylonen @@ -139,6 +139,8 @@ struct Channel { u_int io_ready; /* bitmask of SSH_CHAN_IO_* */ int pfds[4]; /* pollfd entries for rfd/wfd/efd/sock */ int ctl_chan; /* control channel (multiplexed connections) */ + uint32_t ctl_child_id; /* child session for mux controllers */ + int have_ctl_child_id;/* non-zero if ctl_child_id is valid */ int isatty; /* rfd is a tty */ #ifdef _AIX int wfd_isatty; /* wfd is a tty */ @@ -380,6 +382,7 @@ int x11_connect_display(struct ssh *); int x11_create_display_inet(struct ssh *, int, int, int, u_int *, int **); void x11_request_forwarding_with_spoofing(struct ssh *, int, const char *, const char *, const char *, int); +int x11_channel_used_recently(struct ssh *ssh); /* channel close */ diff --git a/cipher.c b/cipher.c index f12daa12343..8a18da2df8d 100644 --- a/cipher.c +++ b/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.121 2024/05/17 02:39:11 jsg Exp $ */ +/* $OpenBSD: cipher.c,v 1.124 2025/03/14 09:49:49 tb Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -143,8 +143,8 @@ const char * compression_alg_list(int compression) { #ifdef WITH_ZLIB - return compression ? "zlib@openssh.com,zlib,none" : - "none,zlib@openssh.com,zlib"; + return compression ? "zlib@openssh.com,none" : + "none,zlib@openssh.com"; #else return "none"; #endif @@ -255,7 +255,7 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, #endif *ccp = NULL; - if ((cc = calloc(sizeof(*cc), 1)) == NULL) + if ((cc = calloc(1, sizeof(*cc))) == NULL) return SSH_ERR_ALLOC_FAIL; cc->plaintext = (cipher->flags & CFLAG_NONE) != 0; @@ -298,8 +298,8 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, goto out; } if (cipher_authlen(cipher) && - !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, - -1, (u_char *)iv)) { + EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, + -1, (u_char *)iv) <= 0) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -369,13 +369,13 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, if (authlen != cipher_authlen(cc->cipher)) return SSH_ERR_INVALID_ARGUMENT; /* increment IV */ - if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, - 1, lastiv)) + if (EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, + 1, lastiv) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; /* set tag on decryption */ if (!cc->encrypt && - !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, - authlen, (u_char *)src + aadlen + len)) + EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, + authlen, (u_char *)src + aadlen + len) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; } if (aadlen) { @@ -395,8 +395,8 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, return cc->encrypt ? SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID; if (cc->encrypt && - !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG, - authlen, dest + aadlen + len)) + EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG, + authlen, dest + aadlen + len) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; } return 0; @@ -465,10 +465,10 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, size_t len) if ((size_t)evplen != len) return SSH_ERR_INVALID_ARGUMENT; if (cipher_authlen(c)) { - if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, - len, iv)) + if (EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, len, + iv) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; - } else if (!EVP_CIPHER_CTX_get_iv(cc->evp, iv, len)) + } else if (EVP_CIPHER_CTX_get_iv(cc->evp, iv, len) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; #endif return 0; @@ -495,8 +495,8 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv, size_t len) return SSH_ERR_INVALID_ARGUMENT; if (cipher_authlen(c)) { /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ - if (!EVP_CIPHER_CTX_ctrl(cc->evp, - EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) + if (EVP_CIPHER_CTX_ctrl(cc->evp, + EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv) <= 0) return SSH_ERR_LIBCRYPTO_ERROR; } else if (!EVP_CIPHER_CTX_set_iv(cc->evp, iv, evplen)) return SSH_ERR_LIBCRYPTO_ERROR; diff --git a/clientloop.c b/clientloop.c index 2d6e42b028f..f3350a83b1f 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.408 2024/07/01 04:31:17 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.410 2024/12/03 22:30:03 jsg Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -667,9 +667,10 @@ obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout, if (just_started) return 1; - /* Don't arm output fd for poll until the timing interval has elapsed */ + /* Don't arm output fd for poll until the timing interval has elapsed... */ if (timespeccmp(&now, &next_interval, <)) - return 0; + /* ...unless there's x11 communication happening */ + return x11_channel_used_recently(ssh); /* Calculate number of intervals missed since the last check */ n = (now.tv_sec - next_interval.tv_sec) * 1000LL * 1000 * 1000; diff --git a/config.h.in b/config.h.in index ca9f7d8c98b..6a0b89a75d3 100644 --- a/config.h.in +++ b/config.h.in @@ -222,6 +222,12 @@ /* Define to 1 if you have the `aug_get_machine' function. */ #undef HAVE_AUG_GET_MACHINE +/* Define to 1 if you have the `auth_hostok' function. */ +#undef HAVE_AUTH_HOSTOK + +/* Define to 1 if you have the `auth_timeok' function. */ +#undef HAVE_AUTH_TIMEOK + /* Define to 1 if you have the `b64_ntop' function. */ #undef HAVE_B64_NTOP @@ -357,10 +363,22 @@ don't. */ #undef HAVE_DECL_HOWMANY +/* Define to 1 if you have the declaration of `htole64', and to 0 if you + don't. */ +#undef HAVE_DECL_HTOLE64 + /* Define to 1 if you have the declaration of `h_errno', and to 0 if you don't. */ #undef HAVE_DECL_H_ERRNO +/* Define to 1 if you have the declaration of `le32toh', and to 0 if you + don't. */ +#undef HAVE_DECL_LE32TOH + +/* Define to 1 if you have the declaration of `le64toh', and to 0 if you + don't. */ +#undef HAVE_DECL_LE64TOH + /* Define to 1 if you have the declaration of `loginfailed', and to 0 if you don't. */ #undef HAVE_DECL_LOGINFAILED @@ -389,14 +407,6 @@ don't. */ #undef HAVE_DECL_OFFSETOF -/* Define to 1 if you have the declaration of `OPENSSL_IS_BORINGSSL', and to 0 - if you don't. */ -#undef HAVE_DECL_OPENSSL_IS_BORINGSSL - -/* Define to 1 if you have the declaration of `OPENSSL_NO_DSA', and to 0 if - you don't. */ -#undef HAVE_DECL_OPENSSL_NO_DSA - /* Define to 1 if you have the declaration of `O_NONBLOCK', and to 0 if you don't. */ #undef HAVE_DECL_O_NONBLOCK @@ -511,6 +521,12 @@ /* Define to 1 if you have the `EVP_DigestInit_ex' function. */ #undef HAVE_EVP_DIGESTINIT_EX +/* Define to 1 if you have the `EVP_DigestSign' function. */ +#undef HAVE_EVP_DIGESTSIGN + +/* Define to 1 if you have the `EVP_DigestVerify' function. */ +#undef HAVE_EVP_DIGESTVERIFY + /* Define to 1 if you have the `EVP_MD_CTX_cleanup' function. */ #undef HAVE_EVP_MD_CTX_CLEANUP @@ -1393,9 +1409,6 @@ /* define if you have struct timeval */ #undef HAVE_STRUCT_TIMEVAL -/* Define to 1 if you have the `swap32' function. */ -#undef HAVE_SWAP32 - /* Define to 1 if you have the `sysconf' function. */ #undef HAVE_SYSCONF @@ -1703,6 +1716,9 @@ EOPNOTSUPP. */ #undef LINK_OPNOTSUPP_ERRNO +/* Lock all memory to protect sshd against Linux kcompactd */ +#undef LINUX_MEMLOCK_ONFAULT + /* Adjust Linux out-of-memory killer */ #undef LINUX_OOM_ADJUST @@ -1727,6 +1743,9 @@ /* Set this to your mail directory if you do not have _PATH_MAILDIR */ #undef MAIL_DIRECTORY +/* Define if your compiler lacks __builtin_popcount */ +#undef MISSING_BUILTIN_POPCOUNT + /* Need setpgrp to for controlling tty */ #undef NEED_SETPGRP @@ -1818,9 +1837,6 @@ /* no privsep sandboxing */ #undef SANDBOX_NULL -/* Sandbox using pledge(2) */ -#undef SANDBOX_PLEDGE - /* Sandbox using setrlimit(2) */ #undef SANDBOX_RLIMIT @@ -1836,9 +1852,6 @@ /* Sandbox using Solaris/Illumos privileges */ #undef SANDBOX_SOLARIS -/* Sandbox using systrace(4) */ -#undef SANDBOX_SYSTRACE - /* Specify the system call convention in use */ #undef SECCOMP_AUDIT_ARCH @@ -1962,6 +1975,9 @@ /* Define if you have Solaris projects */ #undef USE_SOLARIS_PROJECTS +/* Use libwtmpdb for sshd */ +#undef USE_WTMPDB + /* compiler variable declarations after code */ #undef VARIABLE_DECLARATION_AFTER_CODE @@ -1974,9 +1990,6 @@ /* Define if you want to enable AIX4's authenticate function */ #undef WITH_AIXAUTHENTICATE -/* DSA keys explicitly enabled */ -#undef WITH_DSA - /* Define if you have/want arrays (cluster-wide session management, not C arrays) */ #undef WITH_IRIX_ARRAY diff --git a/configure b/configure index 07d19fd30cb..ae9866f288f 100755 --- a/configure +++ b/configure @@ -678,11 +678,13 @@ GSSLIBS KRB5CONF SSHDLIBS SSH_PRIVSEP_USER +SK_STANDALONE LIBFIDO2 SK_DUMMY_LIBRARY OPENSSL_BIN openssl_bin PICFLAG +LIBWTMPDB LIBEDIT LDNSCONFIG LIBOBJS @@ -784,6 +786,7 @@ with_ldflags with_ldflags_after with_libs with_Werror +with_linux_memlock_onfault with_solaris_contracts with_solaris_projects with_solaris_privs @@ -792,12 +795,13 @@ with_zlib with_zlib_version_check with_ldns with_libedit +with_wtmpdb with_audit with_pie enable_pkcs11 enable_security_key with_security_key_builtin -enable_dsa_keys +with_security_key_standalone with_ssl_dir with_openssl_header_check with_ssl_engine @@ -1467,7 +1471,6 @@ Optional Features: --disable-largefile omit support for large files --disable-pkcs11 disable PKCS#11 support code [no] --disable-security-key disable U2F/FIDO support code no - --enable-dsa-keys enable DSA key support no --disable-strip Disable calling strip(1) on install --disable-etc-default-login Disable using PATH from /etc/default/login no --disable-fd-passing disable file descriptor passsing no @@ -1495,6 +1498,7 @@ Optional Packages: --with-ldflags-after Specify additional flags to pass to linker after configure --with-libs Specify additional libraries to link with --with-Werror Build main code with -Werror + --with-linux-memlock-onfault Enables memory locking on Linux --with-solaris-contracts Enable Solaris process contracts (experimental) --with-solaris-projects Enable Solaris projects (experimental) --with-solaris-privs Enable Solaris/Illumos privileges (experimental) @@ -1503,9 +1507,11 @@ Optional Packages: --without-zlib-version-check Disable zlib version check --with-ldns[=PATH] Use ldns for DNSSEC support (optionally in PATH) --with-libedit[=PATH] Enable libedit support for sftp + --with-wtmpdb[=PATH] Enable wtmpdb support for sshd --with-audit=module Enable audit support (modules=debug,bsm,linux) --with-pie Build Position Independent Executables if possible --with-security-key-builtin include builtin U2F/FIDO support + --with-security-key-standalone build standalone sk-libfido2 SecurityKeyProvider --with-ssl-dir=PATH Specify path to OpenSSL installation --without-openssl-header-check Disable OpenSSL version consistency check --with-ssl-engine Enable OpenSSL (hardware) ENGINE support @@ -1514,7 +1520,7 @@ Optional Packages: --with-pam Enable PAM support --with-pam-service=name Specify PAM service name --with-privsep-user=user Specify non-privileged user for privilege separation - --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter, systrace, pledge) + --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter) --with-selinux Enable SELinux support --with-kerberos5=PATH Enable Kerberos 5 support --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty) @@ -5974,16 +5980,6 @@ if test "x$ac_cv_have_decl_LONG_LONG_MAX" = xyes then : have_long_long_max=1 fi -ac_fn_check_decl "$LINENO" "SYSTR_POLICY_KILL" "ac_cv_have_decl_SYSTR_POLICY_KILL" " - #include - #include - #include - -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_SYSTR_POLICY_KILL" = xyes -then : - have_systr_policy_kill=1 -fi ac_fn_check_decl "$LINENO" "RLIMIT_NPROC" "ac_cv_have_decl_RLIMIT_NPROC" " #include #include @@ -11325,6 +11321,65 @@ then : fi +ac_fn_check_decl "$LINENO" "le32toh" "ac_cv_have_decl_le32toh" " +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_le32toh" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_LE32TOH $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "le64toh" "ac_cv_have_decl_le64toh" " +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_le64toh" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_LE64TOH $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "htole64" "ac_cv_have_decl_htole64" " +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_htole64" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_HTOLE64 $ac_have_decl" >>confdefs.h + + # On some platforms (eg SunOS4) sys/audit.h requires sys/[time|types|label.h] # to be included first. ac_fn_c_check_header_compile "$LINENO" "sys/audit.h" "ac_cv_header_sys_audit_h" " @@ -11506,6 +11561,9 @@ SPP_MSG="no" # the --with-solaris-privs option and --with-sandbox=solaris). SOLARIS_PRIVS="no" +# Default shared library extension +SHLIBEXT=".so" + # Check for some target-specific stuff case "$host" in *-*-aix*) @@ -11519,6 +11577,7 @@ printf %s "checking if compiler allows macro redefinitions... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include #define testmacro foo #define testmacro bar int @@ -11974,6 +12033,7 @@ printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext } + SHLIBEXT=".dll" ;; *-*-dgux*) @@ -12138,6 +12198,7 @@ fi printf "%s\n" "#define BROKEN_POLL 1" >>confdefs.h + SHLIBEXT=".dylib" ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS" @@ -12390,6 +12451,46 @@ printf "%s\n" "#define _PATH_BTMP \"/var/log/btmp\"" >>confdefs.h printf "%s\n" "#define LINUX_OOM_ADJUST 1" >>confdefs.h +# Check whether --with-linux-memlock-onfault was given. +if test ${with_linux_memlock_onfault+y} +then : + withval=$with_linux_memlock_onfault; + if test "x$withval" != "xno" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for MCL_ONFAULT" >&5 +printf %s "checking for MCL_ONFAULT... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include +int +main (void) +{ + mlockall(MCL_FUTURE | MCL_ONFAULT); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: supported" >&5 +printf "%s\n" "supported" >&6; } + +printf "%s\n" "#define LINUX_MEMLOCK_ONFAULT 1" >>confdefs.h + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not supported" >&5 +printf "%s\n" "not supported" >&6; } + as_fn_error $? "MCL_ONFAULT is not available on your system" "$LINENO" 5 + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + +fi + + + printf "%s\n" "#define SYSTEMD_NOTIFY 1" >>confdefs.h inet6_default_4in6=yes @@ -12706,7 +12807,7 @@ printf "%s\n" "#define SSH_TUN_OPENBSD 1" >>confdefs.h printf "%s\n" "#define SYSLOG_R_SAFE_IN_SIGHAND 1" >>confdefs.h - TEST_MALLOC_OPTIONS="AFGJPRX" + TEST_MALLOC_OPTIONS="SJRU" ;; *-*-solaris*) if test "x$withval" != "xno" ; then @@ -13317,6 +13418,9 @@ EOD printf "%s\n" "#define BROKEN_SETVBUF 1" >>confdefs.h ;; +*-*-gnu*) + CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_GNU_SOURCE" + ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking compiler and flags for sanity" >&5 @@ -15321,6 +15425,95 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi +# Check whether user wants wtmpdb support +WTMPDB_MSG="no" + +# Check whether --with-wtmpdb was given. +if test ${with_wtmpdb+y} +then : + withval=$with_wtmpdb; if test "x$withval" != "xno" ; then + if test "x$withval" = "xyes" ; then + if test "x$PKGCONFIG" != "xno"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $PKGCONFIG knows about wtmpdb" >&5 +printf %s "checking if $PKGCONFIG knows about wtmpdb... " >&6; } + if "$PKGCONFIG" libwtmpdb; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + use_pkgconfig_for_libwtmpdb=yes + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + fi + fi + else + CPPFLAGS="$CPPFLAGS -I${withval}/include" + if test -n "${rpath_opt}"; then + LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}" + else + LDFLAGS="-L${withval}/lib ${LDFLAGS}" + fi + fi + if test "x$use_pkgconfig_for_libwtmpdb" = "xyes"; then + LIBWTMPDB=`$PKGCONFIG --libs libwtmpdb` + CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libwtmpdb`" + else + LIBWTMPDB="-lwtmpdb" + fi + OTHERLIBS=`echo $LIBWTMPDB | sed 's/-lwtmpdb//'` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for wtmpdb_login in -lwtmpdb" >&5 +printf %s "checking for wtmpdb_login in -lwtmpdb... " >&6; } +if test ${ac_cv_lib_wtmpdb_wtmpdb_login+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lwtmpdb $OTHERLIBS + $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char wtmpdb_login (); +int +main (void) +{ +return wtmpdb_login (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_wtmpdb_wtmpdb_login=yes +else $as_nop + ac_cv_lib_wtmpdb_wtmpdb_login=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wtmpdb_wtmpdb_login" >&5 +printf "%s\n" "$ac_cv_lib_wtmpdb_wtmpdb_login" >&6; } +if test "x$ac_cv_lib_wtmpdb_wtmpdb_login" = xyes +then : + +printf "%s\n" "#define USE_WTMPDB 1" >>confdefs.h + + WTMPDB_MSG="yes" + + +else $as_nop + as_fn_error $? "libwtmpdb not found" "$LINENO" 5 +fi + + fi + +fi + + + AUDIT_MODULE=none # Check whether --with-audit was given. @@ -15875,6 +16068,18 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS="$SAVED_CFLAGS" +ac_fn_c_check_func "$LINENO" "auth_hostok" "ac_cv_func_auth_hostok" +if test "x$ac_cv_func_auth_hostok" = xyes +then : + printf "%s\n" "#define HAVE_AUTH_HOSTOK 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "auth_timeok" "ac_cv_func_auth_timeok" +if test "x$ac_cv_func_auth_timeok" = xyes +then : + printf "%s\n" "#define HAVE_AUTH_TIMEOK 1" >>confdefs.h + +fi ac_fn_c_check_func "$LINENO" "Blowfish_initstate" "ac_cv_func_Blowfish_initstate" if test "x$ac_cv_func_Blowfish_initstate" = xyes then : @@ -16624,12 +16829,6 @@ if test "x$ac_cv_func_strtoull" = xyes then : printf "%s\n" "#define HAVE_STRTOULL 1" >>confdefs.h -fi -ac_fn_c_check_func "$LINENO" "swap32" "ac_cv_func_swap32" -if test "x$ac_cv_func_swap32" = xyes -then : - printf "%s\n" "#define HAVE_SWAP32 1" >>confdefs.h - fi ac_fn_c_check_func "$LINENO" "sysconf" "ac_cv_func_sysconf" if test "x$ac_cv_func_sysconf" = xyes @@ -16717,6 +16916,40 @@ then : fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports __builtin_popcount" >&5 +printf %s "checking whether compiler supports __builtin_popcount... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + +int +main (void) +{ + int x = 123, y; + y = __builtin_popcount(123); + exit(y == 6 ? 0 : -1); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +printf "%s\n" "#define MISSING_BUILTIN_POPCOUNT 1" >>confdefs.h + + + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ac_fn_check_decl "$LINENO" "bzero" "ac_cv_have_decl_bzero" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_bzero" = xyes then : @@ -16859,15 +17092,12 @@ then : fi -enable_dsa= -# Check whether --enable-dsa-keys was given. -if test ${enable_dsa_keys+y} -then : - enableval=$enable_dsa_keys; - if test "x$enableval" != "xno" ; then - enable_dsa=1 - fi +enable_sk_standalone= +# Check whether --with-security-key-standalone was given. +if test ${with_security_key_standalone+y} +then : + withval=$with_security_key_standalone; enable_sk_standalone=$withval fi @@ -18944,6 +19174,18 @@ if test "x$ac_cv_func_DSA_generate_parameters_ex" = xyes then : printf "%s\n" "#define HAVE_DSA_GENERATE_PARAMETERS_EX 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "EVP_DigestSign" "ac_cv_func_EVP_DigestSign" +if test "x$ac_cv_func_EVP_DigestSign" = xyes +then : + printf "%s\n" "#define HAVE_EVP_DIGESTSIGN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "EVP_DigestVerify" "ac_cv_func_EVP_DigestVerify" +if test "x$ac_cv_func_EVP_DigestVerify" = xyes +then : + printf "%s\n" "#define HAVE_EVP_DIGESTVERIFY 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "EVP_DigestFinal_ex" "ac_cv_func_EVP_DigestFinal_ex" if test "x$ac_cv_func_EVP_DigestFinal_ex" = xyes @@ -19442,61 +19684,19 @@ printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - - openssl_dsa=no - if test ! -z "$enable_dsa" ; then - ac_fn_check_decl "$LINENO" "OPENSSL_NO_DSA" "ac_cv_have_decl_OPENSSL_NO_DSA" " #include - -" "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_OPENSSL_NO_DSA" = xyes -then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 fi -printf "%s\n" "#define HAVE_DECL_OPENSSL_NO_DSA $ac_have_decl" >>confdefs.h -if test $ac_have_decl = 1 -then : -else $as_nop +# PKCS11/U2F depend on OpenSSL and dlopen(). +enable_pkcs11=yes +enable_sk=yes - ac_fn_check_decl "$LINENO" "OPENSSL_IS_BORINGSSL" "ac_cv_have_decl_OPENSSL_IS_BORINGSSL" " #include +ac_fn_check_decl "$LINENO" "OPENSSL_IS_AWSLC" "ac_cv_have_decl_OPENSSL_IS_AWSLC" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" -if test "x$ac_cv_have_decl_OPENSSL_IS_BORINGSSL" = xyes +if test "x$ac_cv_have_decl_OPENSSL_IS_AWSLC" = xyes then : - ac_have_decl=1 -else $as_nop - ac_have_decl=0 -fi -printf "%s\n" "#define HAVE_DECL_OPENSSL_IS_BORINGSSL $ac_have_decl" >>confdefs.h -if test $ac_have_decl = 1 -then : - -else $as_nop - openssl_dsa=yes -fi - - + enable_pkcs11="disabled; PKCS#11 not supported with AWS-LC" fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable DSA key support" >&5 -printf %s "checking whether to enable DSA key support... " >&6; } - if test "x$openssl_dsa" = "xno"; then - as_fn_error $? "DSA requested but not supported by OpenSSL" "$LINENO" 5 - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - -printf "%s\n" "#define WITH_DSA 1" >>confdefs.h - - fi - fi -fi - -# PKCS11/U2F depend on OpenSSL and dlopen(). -enable_pkcs11=yes -enable_sk=yes if test "x$openssl" != "xyes" ; then enable_pkcs11="disabled; missing libcrypto" fi @@ -19697,6 +19897,21 @@ fi fi fi +# Check for standalone SecurityKeyProvider +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build standalone sk-libfido2" >&5 +printf %s "checking whether to build standalone sk-libfido2... " >&6; } +if test "x$enable_sk_standalone" = "xyes" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + SK_STANDALONE=sk-libfido2$SHLIBEXT + +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + SK_STANDALONE="" + +fi + ac_fn_c_check_func "$LINENO" "arc4random" "ac_cv_func_arc4random" if test "x$ac_cv_func_arc4random" = xyes then : @@ -20515,23 +20730,7 @@ fi fi -if test "x$sandbox_arg" = "xpledge" || \ - ( test -z "$sandbox_arg" && test "x$ac_cv_func_pledge" = "xyes" ) ; then - test "x$ac_cv_func_pledge" != "xyes" && \ - as_fn_error $? "pledge sandbox requires pledge(2) support" "$LINENO" 5 - SANDBOX_STYLE="pledge" - -printf "%s\n" "#define SANDBOX_PLEDGE 1" >>confdefs.h - -elif test "x$sandbox_arg" = "xsystrace" || \ - ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then - test "x$have_systr_policy_kill" != "x1" && \ - as_fn_error $? "systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support" "$LINENO" 5 - SANDBOX_STYLE="systrace" - -printf "%s\n" "#define SANDBOX_SYSTRACE 1" >>confdefs.h - -elif test "x$sandbox_arg" = "xdarwin" || \ +if test "x$sandbox_arg" = "xdarwin" || \ ( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \ test "x$ac_cv_header_sandbox_h" = "xyes") ; then test "x$ac_cv_func_sandbox_init" != "xyes" -o \ @@ -22205,7 +22404,11 @@ int main(void) long long num = 0x7fffffffffffffffll; #endif strcpy(expected_out, "9223372036854775807"); +#if (SIZEOF_LONG_INT == 8) + snprintf(buf, mazsize, "%ld", num); +#else snprintf(buf, mazsize, "%lld", num); +#endif if(strcmp(buf, expected_out) != 0) exit(1); exit(0); @@ -26291,8 +26494,8 @@ CFLAGS="${CFLAGS} ${CFLAGS_AFTER}" LDFLAGS="${LDFLAGS} ${LDFLAGS_AFTER}" # Make a copy of CFLAGS/LDFLAGS without PIE options. -LDFLAGS_NOPIE=`echo "$LDFLAGS" | sed 's/ -pie//'` -CFLAGS_NOPIE=`echo "$CFLAGS" | sed 's/ -fPIE//'` +LDFLAGS_NOPIE=`echo "$LDFLAGS" | sed 's/^-pie //;s/ -pie//g'` +CFLAGS_NOPIE=`echo "$CFLAGS" | sed 's/^-fPIE //;s/ -fPIE//g'` diff --git a/configure.ac b/configure.ac index 2eede34c3cf..ee77a0484b1 100644 --- a/configure.ac +++ b/configure.ac @@ -114,11 +114,6 @@ AC_C_INLINE AC_CHECK_DECL([LLONG_MAX], [have_llong_max=1], , [#include ]) AC_CHECK_DECL([LONG_LONG_MAX], [have_long_long_max=1], , [#include ]) -AC_CHECK_DECL([SYSTR_POLICY_KILL], [have_systr_policy_kill=1], , [ - #include - #include - #include -]) AC_CHECK_DECL([RLIMIT_NPROC], [AC_DEFINE([HAVE_RLIMIT_NPROC], [], [sys/resource.h has RLIMIT_NPROC])], , [ #include @@ -536,6 +531,18 @@ AC_CHECK_HEADERS([ \ wchar.h \ ]) +AC_CHECK_DECLS([le32toh, le64toh, htole64], [], [], [ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_ENDIAN_H +# include +#endif +]) + # On some platforms (eg SunOS4) sys/audit.h requires sys/[time|types|label.h] # to be included first. AC_CHECK_HEADERS([sys/audit.h], [], [], [ @@ -619,6 +626,9 @@ SPP_MSG="no" # the --with-solaris-privs option and --with-sandbox=solaris). SOLARIS_PRIVS="no" +# Default shared library extension +SHLIBEXT=".so" + # Check for some target-specific stuff case "$host" in *-*-aix*) @@ -630,6 +640,7 @@ case "$host" in AC_MSG_CHECKING([if compiler allows macro redefinitions]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[ +#include #define testmacro foo #define testmacro bar]], [[ exit(0); ]])], @@ -737,6 +748,7 @@ case "$host" in # Cygwin defines optargs, optargs as declspec(dllimport) for historical # reasons which cause compile warnings, so we disable those warnings. OSSH_CHECK_CFLAG_COMPILE([-Wno-attributes]) + SHLIBEXT=".dll" ;; *-*-dgux*) AC_DEFINE([IP_TOS_IS_BROKEN], [1], @@ -796,6 +808,7 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) # cf. Apple bug 3710161 (not public, but searchable) AC_DEFINE([BROKEN_POLL], [1], [System poll(2) implementation is broken]) + SHLIBEXT=".dylib" ;; *-*-dragonfly*) SSHDLIBS="$SSHDLIBS" @@ -915,6 +928,27 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts]) AC_DEFINE([USE_BTMP]) AC_DEFINE([LINUX_OOM_ADJUST], [1], [Adjust Linux out-of-memory killer]) + AC_ARG_WITH([linux-memlock-onfault], + [ --with-linux-memlock-onfault Enables memory locking on Linux], + [ + if test "x$withval" != "xno" ; then + AC_MSG_CHECKING([for MCL_ONFAULT]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ #include ]], + [[ mlockall(MCL_FUTURE | MCL_ONFAULT); ]], + )], + [ + AC_MSG_RESULT([supported]) + AC_DEFINE([LINUX_MEMLOCK_ONFAULT], [1], + [Lock all memory to protect sshd against Linux kcompactd] )], + [ + AC_MSG_RESULT([not supported]) + AC_MSG_ERROR([MCL_ONFAULT is not available on your system]) + ]) + fi + ], + ) + AC_DEFINE([SYSTEMD_NOTIFY], [1], [Have sshd notify systemd on start/reload]) inet6_default_4in6=yes case `uname -r` in @@ -1093,7 +1127,7 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE([SSH_TUN_OPENBSD], [1], [Open tunnel devices the OpenBSD way]) AC_DEFINE([SYSLOG_R_SAFE_IN_SIGHAND], [1], [syslog_r function is safe to use in in a signal handler]) - TEST_MALLOC_OPTIONS="AFGJPRX" + TEST_MALLOC_OPTIONS="SJRU" ;; *-*-solaris*) if test "x$withval" != "xno" ; then @@ -1772,6 +1806,48 @@ AC_ARG_WITH([libedit], fi ] ) +# Check whether user wants wtmpdb support +WTMPDB_MSG="no" +AC_ARG_WITH([wtmpdb], + [ --with-wtmpdb[[=PATH]] Enable wtmpdb support for sshd], + [ if test "x$withval" != "xno" ; then + if test "x$withval" = "xyes" ; then + if test "x$PKGCONFIG" != "xno"; then + AC_MSG_CHECKING([if $PKGCONFIG knows about wtmpdb]) + if "$PKGCONFIG" libwtmpdb; then + AC_MSG_RESULT([yes]) + use_pkgconfig_for_libwtmpdb=yes + else + AC_MSG_RESULT([no]) + fi + fi + else + CPPFLAGS="$CPPFLAGS -I${withval}/include" + if test -n "${rpath_opt}"; then + LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}" + else + LDFLAGS="-L${withval}/lib ${LDFLAGS}" + fi + fi + if test "x$use_pkgconfig_for_libwtmpdb" = "xyes"; then + LIBWTMPDB=`$PKGCONFIG --libs libwtmpdb` + CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libwtmpdb`" + else + LIBWTMPDB="-lwtmpdb" + fi + OTHERLIBS=`echo $LIBWTMPDB | sed 's/-lwtmpdb//'` + AC_CHECK_LIB([wtmpdb], [wtmpdb_login], + [ AC_DEFINE([USE_WTMPDB], [1], [Use libwtmpdb for sshd]) + WTMPDB_MSG="yes" + AC_SUBST([LIBWTMPDB]) + ], + [ AC_MSG_ERROR([libwtmpdb not found]) ], + [ $OTHERLIBS ] + ) + fi ] +) + + AUDIT_MODULE=none AC_ARG_WITH([audit], [ --with-audit=module Enable audit support (modules=debug,bsm,linux)], @@ -1886,6 +1962,8 @@ AC_SUBST([PICFLAG]) dnl Checks for library functions. Please keep in alphabetical order AC_CHECK_FUNCS([ \ + auth_hostok \ + auth_timeok \ Blowfish_initstate \ Blowfish_expandstate \ Blowfish_expand0state \ @@ -2011,7 +2089,6 @@ AC_CHECK_FUNCS([ \ strtoll \ strtoul \ strtoull \ - swap32 \ sysconf \ tcgetpgrp \ timegm \ @@ -2028,6 +2105,19 @@ AC_CHECK_FUNCS([ \ warn \ ]) +AC_MSG_CHECKING([whether compiler supports __builtin_popcount]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + ]], + [[ int x = 123, y; + y = __builtin_popcount(123); + exit(y == 6 ? 0 : -1); ]])], + [ AC_MSG_RESULT([yes]) ], [ + AC_MSG_RESULT([no]) + AC_DEFINE([MISSING_BUILTIN_POPCOUNT], [1], [Define if your compiler lacks __builtin_popcount]) + ] +) + AC_CHECK_DECLS([bzero, memmem]) dnl Wide character support. @@ -2083,14 +2173,10 @@ AC_ARG_WITH([security-key-builtin], [ enable_sk_internal=$withval ] ) -enable_dsa= -AC_ARG_ENABLE([dsa-keys], - [ --enable-dsa-keys enable DSA key support [no]], - [ - if test "x$enableval" != "xno" ; then - enable_dsa=1 - fi - ] +enable_sk_standalone= +AC_ARG_WITH([security-key-standalone], + [ --with-security-key-standalone build standalone sk-libfido2 SecurityKeyProvider], + [ enable_sk_standalone=$withval ] ) AC_SEARCH_LIBS([dlopen], [dl]) @@ -2981,6 +3067,8 @@ if test "x$openssl" = "xyes" ; then BN_is_prime_ex \ DES_crypt \ DSA_generate_parameters_ex \ + EVP_DigestSign \ + EVP_DigestVerify \ EVP_DigestFinal_ex \ EVP_DigestInit_ex \ EVP_MD_CTX_cleanup \ @@ -3199,31 +3287,17 @@ if test "x$openssl" = "xyes" ; then AC_MSG_RESULT([no]) ] ) - - openssl_dsa=no - if test ! -z "$enable_dsa" ; then - AC_CHECK_DECLS([OPENSSL_NO_DSA], [], [ - AC_CHECK_DECLS([OPENSSL_IS_BORINGSSL], [], - [ openssl_dsa=yes ], - [ #include ] - ) - ], - [ #include ] - ) - AC_MSG_CHECKING([whether to enable DSA key support]) - if test "x$openssl_dsa" = "xno"; then - AC_MSG_ERROR([DSA requested but not supported by OpenSSL]) - else - AC_MSG_RESULT([yes]) - AC_DEFINE([WITH_DSA], [1], - [DSA keys explicitly enabled]) - fi - fi fi # PKCS11/U2F depend on OpenSSL and dlopen(). enable_pkcs11=yes enable_sk=yes + +AC_CHECK_DECL([OPENSSL_IS_AWSLC], + [enable_pkcs11="disabled; PKCS#11 not supported with AWS-LC"], + [], + [#include ] +) if test "x$openssl" != "xyes" ; then enable_pkcs11="disabled; missing libcrypto" fi @@ -3318,6 +3392,16 @@ if test "x$enable_sk" = "xyes" -a "x$enable_sk_internal" != "xno" ; then fi fi +# Check for standalone SecurityKeyProvider +AC_MSG_CHECKING([whether to build standalone sk-libfido2]) +if test "x$enable_sk_standalone" = "xyes" ; then + AC_MSG_RESULT([yes]) + AC_SUBST([SK_STANDALONE], [sk-libfido2$SHLIBEXT]) +else + AC_MSG_RESULT([no]) + AC_SUBST([SK_STANDALONE], [""]) +fi + AC_CHECK_FUNCS([ \ arc4random \ arc4random_buf \ @@ -3610,7 +3694,7 @@ AC_CHECK_TYPES([nfds_t], , , [ # Decide which sandbox style to use sandbox_arg="" AC_ARG_WITH([sandbox], - [ --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter, systrace, pledge)], + [ --with-sandbox=style Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter)], [ if test "x$withval" = "xyes" ; then sandbox_arg="" @@ -3727,19 +3811,7 @@ if test "x$sandbox_arg" != "xno"; then ) fi -if test "x$sandbox_arg" = "xpledge" || \ - ( test -z "$sandbox_arg" && test "x$ac_cv_func_pledge" = "xyes" ) ; then - test "x$ac_cv_func_pledge" != "xyes" && \ - AC_MSG_ERROR([pledge sandbox requires pledge(2) support]) - SANDBOX_STYLE="pledge" - AC_DEFINE([SANDBOX_PLEDGE], [1], [Sandbox using pledge(2)]) -elif test "x$sandbox_arg" = "xsystrace" || \ - ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then - test "x$have_systr_policy_kill" != "x1" && \ - AC_MSG_ERROR([systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support]) - SANDBOX_STYLE="systrace" - AC_DEFINE([SANDBOX_SYSTRACE], [1], [Sandbox using systrace(4)]) -elif test "x$sandbox_arg" = "xdarwin" || \ +if test "x$sandbox_arg" = "xdarwin" || \ ( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \ test "x$ac_cv_header_sandbox_h" = "xyes") ; then test "x$ac_cv_func_sandbox_init" != "xyes" -o \ @@ -4358,7 +4430,11 @@ int main(void) long long num = 0x7fffffffffffffffll; #endif strcpy(expected_out, "9223372036854775807"); +#if (SIZEOF_LONG_INT == 8) + snprintf(buf, mazsize, "%ld", num); +#else snprintf(buf, mazsize, "%lld", num); +#endif if(strcmp(buf, expected_out) != 0) exit(1); exit(0); @@ -5654,8 +5730,8 @@ CFLAGS="${CFLAGS} ${CFLAGS_AFTER}" LDFLAGS="${LDFLAGS} ${LDFLAGS_AFTER}" # Make a copy of CFLAGS/LDFLAGS without PIE options. -LDFLAGS_NOPIE=`echo "$LDFLAGS" | sed 's/ -pie//'` -CFLAGS_NOPIE=`echo "$CFLAGS" | sed 's/ -fPIE//'` +LDFLAGS_NOPIE=`echo "$LDFLAGS" | sed 's/^-pie //;s/ -pie//g'` +CFLAGS_NOPIE=`echo "$CFLAGS" | sed 's/^-fPIE //;s/ -fPIE//g'` AC_SUBST([LDFLAGS_NOPIE]) AC_SUBST([CFLAGS_NOPIE]) diff --git a/contrib/cygwin/ssh-user-config b/contrib/cygwin/ssh-user-config index 6fa4bb3eac4..3858722f646 100644 --- a/contrib/cygwin/ssh-user-config +++ b/contrib/cygwin/ssh-user-config @@ -58,7 +58,7 @@ create_identity() { else ssh-keygen -t "${type}" -f "${pwdhome}/.ssh/${file}" > /dev/null fi - if csih_request "Do you want to use this identity to login to this machine?" + if csih_request "Do you want to use this identity to log in to this machine?" then csih_inform "Adding to ${pwdhome}/.ssh/authorized_keys" cat "${pwdhome}/.ssh/${file}.pub" >> "${pwdhome}/.ssh/authorized_keys" diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index 8893f3ad3bc..74116b48513 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec @@ -1,4 +1,4 @@ -%global ver 9.8p1 +%global ver 10.0p1 %global rel 1%{?dist} # OpenSSH privilege separation requires a user & group ID @@ -23,20 +23,12 @@ # Use GTK2 instead of GNOME in gnome-ssh-askpass %global gtk2 1 -# Use build6x options for older RHEL builds -# RHEL 7 not yet supported -%if 0%{?rhel} > 6 -%global build6x 0 -%else -%global build6x 1 -%endif - %global without_openssl 0 # build without openssl where 1.1.1 is not available -%if 0%{?fedora} <= 28 +%if %{defined fedora} && 0%{?fedora} <= 28 %global without_openssl 1 %endif -%if 0%{?rhel} <= 7 +%if %{defined rhel} && 0%{?rhel} <= 7 %global without_openssl 1 %endif @@ -53,14 +45,6 @@ # rpm -ba|--rebuild --define 'no_gtk2 1' %{?no_gtk2:%global gtk2 0} -# Is this a build for RHL 6.x or earlier? -%{?build_6x:%global build6x 1} - -# If this is RHL 6.x, the default configuration has sysconfdir in /usr/etc. -%if %{build6x} -%global _sysconfdir /etc -%endif - # Options for static OpenSSL link: # rpm -ba|--rebuild --define "static_openssl 1" %{?static_openssl:%global static_libcrypto 1} @@ -93,21 +77,13 @@ License: BSD Group: Applications/Internet BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot Obsoletes: ssh -%if %{build6x} -PreReq: initscripts >= 5.00 -%else Requires: initscripts >= 5.20 -%endif BuildRequires: perl %if ! %{without_openssl} BuildRequires: openssl-devel >= 1.1.1 %endif BuildRequires: /bin/login -%if ! %{build6x} BuildRequires: glibc-devel, pam -%else -BuildRequires: /usr/include/security/pam_appl.h -%endif %if ! %{no_x11_askpass} BuildRequires: /usr/include/X11/Xlib.h # Xt development tools @@ -136,9 +112,7 @@ Summary: The OpenSSH server daemon. Group: System Environment/Daemons Obsoletes: ssh-server Requires: openssh = %{version}-%{release}, chkconfig >= 0.9 -%if ! %{build6x} Requires: /etc/pam.d/system-auth -%endif %package askpass Summary: A passphrase dialog for OpenSSH and X. @@ -427,6 +401,8 @@ fi - Remove reference of dropped sshd.pam.old file - Update openssl-devel dependency to require >= 1.1.1 - Build with --without-openssl elsewhere +- Remove ancient build6x config, intended for RHL 6.x + (the distro predating Fedora, not RHEL) * Thu Oct 28 2021 Damien Miller - Remove remaining traces of --with-md5-passwords diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id index da6bd18dd42..dcf579843a7 100644 --- a/contrib/ssh-copy-id +++ b/contrib/ssh-copy-id @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright (c) 1999-2023 Philip Hands +# Copyright (c) 1999-2024 Philip Hands # 2021 Carlos Rodríguez Gili # 2020 Matthias Blümel # 2017 Sebastien Boyron @@ -56,19 +56,19 @@ then a bug describing your setup, and the shell you used to make it work. EOF - printf '%s: ERROR: Less dimwitted shell required.\n' "$0" + printf '%s: ERROR: Less dimwitted shell required.\n' "$0" >&2 exit 1 fi fi # shellcheck disable=SC2010 -DEFAULT_PUB_ID_FILE=$(ls -t "${HOME}"/.ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1) +DEFAULT_PUB_ID_FILE=$(ls -dt "${HOME}"/.ssh/id*.pub 2>/dev/null | grep -v -- '-cert.pub$' | head -n 1) SSH="ssh -a -x" TARGET_PATH=".ssh/authorized_keys" umask 0177 usage () { - printf 'Usage: %s [-h|-?|-f|-n|-s|-x] [-i [identity_file]] [-p port] [-F alternative ssh_config file] [-t target_path] [[-o ] ...] [user@]hostname\n' "$0" >&2 + printf 'Usage: %s [-h|-?|-f|-n|-s|-x] [-i [identity_file]] [-t target_path] [-F ssh_config] [[-o ssh_option] ...] [-p port] [user@]hostname\n' "$0" >&2 printf '\t-f: force mode -- copy keys without trying to check if they are already installed\n' >&2 printf '\t-n: dry run -- no keys are actually copied\n' >&2 printf '\t-s: use sftp -- use sftp instead of executing remote-commands. Can be useful if the remote only allows sftp\n' >&2 @@ -86,7 +86,7 @@ use_id_file() { L_ID_FILE="$1" if [ -z "$L_ID_FILE" ] ; then - printf '%s: ERROR: no ID file found\n' "$0" + printf '%s: ERROR: no ID file found\n' "$0" >&2 exit 1 fi @@ -103,11 +103,10 @@ use_id_file() { ErrMSG=$( { : < "$f" ; } 2>&1 ) || { L_PRIVMSG="" [ "$f" = "$PRIV_ID_FILE" ] && L_PRIVMSG=" (to install the contents of '$PUB_ID_FILE' anyway, look at the -f option)" - printf "\\n%s: ERROR: failed to open ID file '%s': %s\\n" "$0" "$f" "$(printf '%s\n%s\n' "$ErrMSG" "$L_PRIVMSG" | sed -e 's/.*: *//')" + printf "\\n%s: ERROR: failed to open ID file '%s': %s\\n" "$0" "$f" "$(printf '%s\n%s\n' "$ErrMSG" "$L_PRIVMSG" | sed -e 's/.*: *//')" >&2 exit 1 } done - printf '%s: INFO: Source of key(s) to be installed: "%s"\n' "$0" "$PUB_ID_FILE" >&2 GET_ID="cat \"$PUB_ID_FILE\"" } @@ -115,15 +114,31 @@ if [ -n "$SSH_AUTH_SOCK" ] && ssh-add -L >/dev/null 2>&1 ; then GET_ID="ssh-add -L" fi -while getopts "i:o:p:F:t:fnsxh?" OPT +OPTS="io:p:F:t:fnsxh?" + +while getopts "$OPTS" OPT do case "$OPT" in i) [ "${SEEN_OPT_I}" ] && { - printf '\n%s: ERROR: -i option must not be specified more than once\n\n' "$0" + printf '\n%s: ERROR: -i option must not be specified more than once\n\n' "$0" >&2 usage } SEEN_OPT_I="yes" + + # Check for -i's optional parameter + eval "nextarg=\${$OPTIND}" + # shellcheck disable=SC2154 + if [ $OPTIND = $# ]; then + if [ -r "$nextarg" ] && grep -iq ssh "$nextarg"; then + printf '\n%s: ERROR: Missing hostname. Use "-i -- %s" if you really mean to use this as the hostname\n\n' "$0" "$nextarg" >&2 + usage + fi + elif ! expr -- "$nextarg" : "-[$(echo "$OPTS" | tr -d :)-]" >/dev/null ; then + # when not at the last arg, and not followed by an option, -i has an argument + OPTARG="$nextarg" + OPTIND=$((OPTIND + 1)) + fi use_id_file "${OPTARG:-$DEFAULT_PUB_ID_FILE}" ;; o|F) @@ -176,16 +191,28 @@ if [ -z "$(eval $GET_ID)" ] && [ -r "${PUB_ID_FILE:=$DEFAULT_PUB_ID_FILE}" ] ; t use_id_file "$PUB_ID_FILE" fi +printf '%s: INFO: Source of key(s) to be installed: %s\n' "$0" "${GET_ID#cat }" >&2 + # shellcheck disable=SC2086 if [ -z "$(eval $GET_ID)" ] ; then printf '%s: ERROR: No identities found\n' "$0" >&2 exit 1 fi +# assert_scratch_ok() +# ensures that $SCRATCH_DIR is setup. +assert_scratch_ok() { + [ "$SCRATCH_DIR" ] && [ -d "$SCRATCH_DIR" ] && [ -w "$SCRATCH_DIR" ] && return 0 + + printf 'ERROR: Assertion failure: in %s(): scratch_dir was not correctly set up (SCRATCH_DIR = "%s")\n' "$1" "$SCRATCH_DIR" >&2 + return 1 +} + # filter_ids() # tries to log in using the keys piped to it, and filters out any that work filter_ids() { L_SUCCESS="$1" + assert_scratch_ok filter_ids || return L_TMP_ID_FILE="$SCRATCH_DIR"/popids_tmp_id L_OUTPUT_FILE="$SCRATCH_DIR"/popids_output @@ -288,23 +315,24 @@ installkeys_via_sftp() { # repopulate "$@" inside this function eval set -- "$SSH_OPTS" - L_KEYS=$SCRATCH_DIR/authorized_keys - L_SHARED_CON=$SCRATCH_DIR/master-conn + assert_scratch_ok installkeys_via_sftp || return 1 + L_KEYS="$SCRATCH_DIR"/authorized_keys + L_SHARED_CON="$SCRATCH_DIR"/master-conn $SSH -f -N -M -S "$L_SHARED_CON" "$@" - L_CLEANUP="$SSH -S $L_SHARED_CON -O exit 'ignored' >/dev/null 2>&1 ; $SCRATCH_CLEANUP" + L_CLEANUP="$SSH -S '$L_SHARED_CON' -O exit 'ignored' >/dev/null 2>&1 ; $SCRATCH_CLEANUP" #shellcheck disable=SC2064 trap "$L_CLEANUP" EXIT TERM INT QUIT - sftp -b - -o "ControlPath=$L_SHARED_CON" "ignored" <<-EOF || return 1 + sftp -b - -o "ControlPath='$L_SHARED_CON'" "ignored" <<-EOF || return 1 -get "$AUTH_KEY_FILE" "$L_KEYS" EOF # add a newline or create file if it's missing, same like above [ -z "$(tail -1c "$L_KEYS" 2>/dev/null)" ] || echo >> "$L_KEYS" # append the keys being piped in here cat >> "$L_KEYS" - sftp -b - -o "ControlPath=$L_SHARED_CON" "ignored" <<-EOF || return 1 + sftp -b - -o "ControlPath='$L_SHARED_CON'" "ignored" <<-EOF || return 1 -mkdir "$AUTH_KEY_DIR" chmod 700 "$AUTH_KEY_DIR" - put $L_KEYS "$AUTH_KEY_FILE" + put "$L_KEYS" "$AUTH_KEY_FILE" chmod 600 "$AUTH_KEY_FILE" EOF #shellcheck disable=SC2064 @@ -321,7 +349,7 @@ then #shellcheck disable=SC2064 trap "$SCRATCH_CLEANUP" EXIT TERM INT QUIT else - printf '%s: ERROR: failed to create required temporary directory under ~/.ssh\n' "$0" >&2 + printf '%s: ERROR: failed to create required temporary directory under ~/.ssh (HOME="%s")\n' "$0" "$HOME" >&2 exit 1 fi @@ -379,7 +407,7 @@ else Number of key(s) added: $ADDED - Now try logging into the machine, with: "${SFTP:-ssh}${SSH_PORT:+ -${PORT_OPT:-p} $SSH_PORT} ${OPTS_USER_HOST}" + Now try logging into the machine, with: "${SFTP:-ssh} ${SEEN_OPT_I:+-i${PRIV_ID_FILE:+ $PRIV_ID_FILE} }${SSH_PORT:+-${PORT_OPT:-p} $SSH_PORT }${OPTS_USER_HOST}" and check to make sure that only the key(s) you wanted were added. EOF diff --git a/contrib/ssh-copy-id.1 b/contrib/ssh-copy-id.1 index 74eec2f8e21..dbdb45ab822 100644 --- a/contrib/ssh-copy-id.1 +++ b/contrib/ssh-copy-id.1 @@ -1,5 +1,5 @@ .ig \" -*- nroff -*- -Copyright (c) 1999-2023 hands.com Ltd. +Copyright (c) 1999-2024 Philip Hands Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -34,9 +34,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .Op Fl s .Op Fl x .Op Fl i Op Ar identity_file -.Op Fl p Ar port -.Op Fl o Ar ssh_option .Op Fl t Ar target_path +.Op Fl F Ar ssh_config +.Op Bo Fl o Ar ssh_option Bc ... +.Op Fl p Ar port .Op Ar user Ns @ Ns .Ar hostname .Nm @@ -67,7 +68,7 @@ command instead. .Pp The options are as follows: .Bl -tag -width Ds -.It Fl i Ar identity_file +.It Fl i Op Ar identity_file Use only the key(s) contained in .Ar identity_file (rather than looking for identities via @@ -104,11 +105,13 @@ on commands which can be used on the remote side. .It Fl t Ar target_path the path on the target system where the keys should be added (defaults to ".ssh/authorized_keys") -.It Fl p Ar port , Fl o Ar ssh_option -These two options are simply passed through untouched, along with their -argument, to allow one to set the port or other -.Xr ssh 1 -options, respectively. +.It Fl p Ar port +Specifies the port to connect to on the remote host. +.It Fl F Ar ssh_config , Fl o Ar ssh_option +These options are simply passed through untouched (with their argument) +to ssh/sftp, +allowing one to set an alternative config file, +or other options, respectively. .Pp Rather than specifying these as command line options, it is often better to use (per-host) settings in diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec index 45815c9d60c..849e9b61f3b 100644 --- a/contrib/suse/openssh.spec +++ b/contrib/suse/openssh.spec @@ -13,7 +13,7 @@ Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation Name: openssh -Version: 9.8p1 +Version: 10.0p1 URL: https://www.openssh.com/ Release: 1 Source0: openssh-%{version}.tar.gz diff --git a/contrib/win32/install/server.wxs b/contrib/win32/install/server.wxs index c2b98c02bd2..f545f4b4b1a 100644 --- a/contrib/win32/install/server.wxs +++ b/contrib/win32/install/server.wxs @@ -9,6 +9,9 @@ + + + diff --git a/contrib/win32/openssh/OpenSSHBuildHelper.psm1 b/contrib/win32/openssh/OpenSSHBuildHelper.psm1 index b1df3cf225c..17f93036c71 100644 --- a/contrib/win32/openssh/OpenSSHBuildHelper.psm1 +++ b/contrib/win32/openssh/OpenSSHBuildHelper.psm1 @@ -8,7 +8,7 @@ Import-Module $PSScriptRoot\OpenSSHCommonUtils.psm1 -Force [bool] $script:Verbose = $false [string] $script:BuildLogFile = $null <# - Called by Write-BuildMsg to write to the build log, if it exists. + Called by Write-BuildMsg to write to the build log, if it exists. #> function Write-Log { @@ -22,7 +22,7 @@ function Write-Log if (-not ([string]::IsNullOrEmpty($script:BuildLogFile))) { Add-Content -Path $script:BuildLogFile -Value $Message - } + } } <# @@ -94,7 +94,7 @@ function Write-BuildMsg return } - if($PSBoundParameters.ContainsKey("AsInfo")) + if($PSBoundParameters.ContainsKey("AsInfo")) { Write-Log -Message "INFO: $message" if (-not $Silent) @@ -151,7 +151,7 @@ function Start-OpenSSHBootstrap # Add git\cmd to the path $machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE') - $newMachineEnvironmentPath = $machinePath + $newMachineEnvironmentPath = $machinePath $gitCmdPath = "$env:ProgramFiles\git\cmd" if (-not ($machinePath.ToLower().Contains($gitCmdPath.ToLower()))) { @@ -171,10 +171,10 @@ function Start-OpenSSHBootstrap if ($newMachineEnvironmentPath -ne $machinePath) { [Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE') - } + } $sdkVersion = Get-Windows10SDKVersion - if ($null -eq $sdkVersion) + if ($null -eq $sdkVersion) { Get-Chocolatey $packageName = "windows-sdk-10.1" @@ -196,7 +196,7 @@ function Start-OpenSSHBootstrap else { $MSBuildPath = Get-VS2015BuildToolPath } - if ($MSBuildPath | Select-String "2022") + if ($MSBuildPath | Select-String "2022") { $env:vctargetspath = Join-Path $VisualStudioPath "MSBuild\Microsoft\VC\v170\" if ($null -eq $env:VS170COMNTOOLS) @@ -205,11 +205,11 @@ function Start-OpenSSHBootstrap } elseif (-not (Test-Path $env:VS170COMNTOOLS)) { - Write-BuildMsg -AsError -ErrorAction Stop -Message "$env:VS170COMNTOOLS build tools path is invalid" + Write-BuildMsg -AsError -ErrorAction Stop -Message "$env:VS170COMNTOOLS build tools path is invalid" } $VSBuildToolsPath = Get-Item(Join-Path $VisualStudioPath 'vc/auxiliary/build') } - elseif ($MSBuildPath | Select-String "2019") + elseif ($MSBuildPath | Select-String "2019") { $env:vctargetspath = Join-Path $VisualStudioPath "Common7\IDE\VC\VCTargets" Write-BuildMsg -AsVerbose -Message "Setting vctargetspath env var to ${env:vctargetspath}" @@ -219,11 +219,11 @@ function Start-OpenSSHBootstrap } elseif (-not (Test-Path $env:VS160COMNTOOLS)) { - Write-BuildMsg -AsError -ErrorAction Stop -Message "$env:VS160COMNTOOLS build tools path is invalid" + Write-BuildMsg -AsError -ErrorAction Stop -Message "$env:VS160COMNTOOLS build tools path is invalid" } $VSBuildToolsPath = Get-Item(Join-Path $VisualStudioPath 'vc/auxiliary/build') } - elseif ($MSBuildPath | Select-String "2017") + elseif ($MSBuildPath | Select-String "2017") { $env:vctargetspath = Join-Path $VisualStudioPath "Common7\IDE\VC\VCTargets" if ($null -eq $env:VS150COMNTOOLS) @@ -232,11 +232,11 @@ function Start-OpenSSHBootstrap } elseif (-not (Test-Path $env:VS150COMNTOOLS)) { - Write-BuildMsg -AsError -ErrorAction Stop -Message "$env:VS150COMNTOOLS build tools path is invalid" + Write-BuildMsg -AsError -ErrorAction Stop -Message "$env:VS150COMNTOOLS build tools path is invalid" } $VSBuildToolsPath = Get-Item(Join-Path $VisualStudioPath 'vc/auxiliary/build') } - else + else { if($NativeHostArch.ToLower().Startswith('arm')) { @@ -246,7 +246,7 @@ function Start-OpenSSHBootstrap $VSBuildToolsPath = Get-Item(Join-Path -Path $env:VS140COMNTOOLS -ChildPath '../../vc') Write-BuildMsg -AsVerbose -Message 'VC++ 2015 Build Tools already present.' - + if (!$MSBuildPath -or ($null -eq $env:VS140COMNTOOLS)) { Get-Chocolatey $packageName = "vcbuildtools" @@ -287,15 +287,15 @@ function Start-OpenSSHBootstrap Write-BuildMsg -AsVerbose -Message "vcPath: $script:vcPath" -Silent:$silent if ((Test-Path -Path "$script:vcPath\vcvarsall.bat") -eq $false) { - Write-BuildMsg -AsError -ErrorAction Stop -Message "Could not find Visual Studio vcvarsall.bat at $script:vcPath, which means some required develop kits are missing on the machine." + Write-BuildMsg -AsError -ErrorAction Stop -Message "Could not find Visual Studio vcvarsall.bat at $script:vcPath, which means some required develop kits are missing on the machine." } } function Start-OpenSSHPackage { - [CmdletBinding(SupportsShouldProcess=$false)] + [CmdletBinding(SupportsShouldProcess=$false)] param - ( + ( [ValidateSet('x86', 'x64', 'arm64', 'arm')] [string]$NativeHostArch = "x64", @@ -314,10 +314,10 @@ function Start-OpenSSHPackage if($NativeHostArch -ieq 'x86') { $folderName = "Win32" - } + } $buildDir = Join-Path $repositoryRoot ("bin\" + $folderName + "\" + $Configuration) - $payload = "sshd.exe", "sshd-session.exe", "ssh.exe", "ssh-agent.exe", "ssh-add.exe", "sftp.exe" + $payload = "sshd.exe", "sshd-auth.exe", "sshd-session.exe", "ssh.exe", "ssh-agent.exe", "ssh-add.exe", "sftp.exe" $payload += "sftp-server.exe", "scp.exe", "ssh-shellhost.exe", "ssh-keygen.exe", "ssh-keyscan.exe", "ssh-sk-helper.exe", "ssh-pkcs11-helper.exe" $payload += "sshd_config_default", "install-sshd.ps1", "uninstall-sshd.ps1" $payload += "FixHostFilePermissions.ps1", "FixUserFilePermissions.ps1", "OpenSSHUtils.psm1", "OpenSSHUtils.psd1" @@ -335,20 +335,20 @@ function Start-OpenSSHPackage } while((($service = Get-Service ssh-agent -ErrorAction SilentlyContinue) -ne $null) -and ($service.Status -ine 'Stopped')) - { + { Stop-Service ssh-agent -Force - #sleep to wait the servicelog file write + #sleep to wait the servicelog file write Start-Sleep 5 } $packageDir = Join-Path $buildDir $packageName Remove-Item $packageDir -Recurse -Force -ErrorAction SilentlyContinue New-Item $packageDir -Type Directory | Out-Null - + $symbolsDir = Join-Path $buildDir ($packageName + '_Symbols') Remove-Item $symbolsDir -Recurse -Force -ErrorAction SilentlyContinue New-Item $symbolsDir -Type Directory | Out-Null - + foreach ($file in $payload) { if ((-not(Test-Path (Join-Path $buildDir $file)))) { Throw "Cannot find $file under $buildDir. Did you run Build-OpenSSH?" @@ -367,7 +367,7 @@ function Start-OpenSSHPackage #copy libcrypto dll $libreSSLPath = Join-Path $PSScriptRoot "LibreSSL" if (-not $NoOpenSSL.IsPresent) - { + { if($OneCore) { Copy-Item -Path $(Join-Path $libreSSLPath "bin\onecore\$NativeHostArch\libcrypto.dll") -Destination $packageDir -Force -ErrorAction Stop @@ -378,10 +378,10 @@ function Start-OpenSSHPackage Copy-Item -Path $(Join-Path $libreSSLPath "bin\desktop\$NativeHostArch\libcrypto.dll") -Destination $packageDir -Force -ErrorAction Stop Copy-Item -Path $(Join-Path $libreSSLPath "bin\desktop\$NativeHostArch\libcrypto.pdb") -Destination $symbolsDir -Force -ErrorAction Stop } - } + } if ($DestinationPath -ne "") { - if (Test-Path $DestinationPath) { + if (Test-Path $DestinationPath) { Remove-Item $DestinationPath\* -Force -Recurse -ErrorAction SilentlyContinue } else { @@ -403,7 +403,7 @@ function Start-OpenSSHPackage } } Remove-Item $packageDir -Recurse -Force -ErrorAction SilentlyContinue - + if ($DestinationPath -ne "") { Copy-Item -Path $symbolsDir\* -Destination $DestinationPath -Force -Recurse Write-BuildMsg -AsInfo -Message "Copied symbols to $DestinationPath" @@ -425,9 +425,9 @@ function Start-OpenSSHPackage function Copy-OpenSSHUnitTests { - [CmdletBinding(SupportsShouldProcess=$false)] + [CmdletBinding(SupportsShouldProcess=$false)] param - ( + ( [ValidateSet('x86', 'x64', 'arm64', 'arm')] [string]$NativeHostArch = "x64", @@ -447,8 +447,8 @@ function Copy-OpenSSHUnitTests } $buildDir = Join-Path $repositoryRoot ("bin\" + $folderName + "\" + $Configuration) $unittestsDir = Join-Path $buildDir "unittests" - $unitTestFolders = Get-ChildItem -Directory $buildDir\unittest-* - + $unitTestFolders = Get-ChildItem -Directory $buildDir\unittest-* + if ($DestinationPath -ne "") { if (-not (Test-Path $DestinationPath -PathType Container)) { New-Item -ItemType Directory $DestinationPath -Force | Out-Null @@ -456,9 +456,9 @@ function Copy-OpenSSHUnitTests foreach ($folder in $unitTestFolders) { Copy-Item $folder.FullName $DestinationPath\$($folder.Name) -Recurse -Force Write-BuildMsg -AsInfo -Message "Copied $($folder.FullName) to $DestinationPath\$($folder.Name)." - } + } } - else { + else { if(Test-Path ($unittestsDir + '.zip') -PathType Leaf) { Remove-Item ($unittestsDir + '.zip') -Force -ErrorAction SilentlyContinue } @@ -476,9 +476,9 @@ function Copy-OpenSSHUnitTests function Start-OpenSSHBuild { - [CmdletBinding(SupportsShouldProcess=$false)] + [CmdletBinding(SupportsShouldProcess=$false)] param - ( + ( [ValidateSet('x86', 'x64', 'arm64', 'arm')] [string]$NativeHostArch = "x64", @@ -488,7 +488,7 @@ function Start-OpenSSHBuild [switch]$NoOpenSSL, [switch]$OneCore - ) + ) $script:BuildLogFile = $null [System.IO.DirectoryInfo] $repositoryRoot = Get-RepositoryRoot @@ -512,8 +512,8 @@ function Start-OpenSSHBuild Start-OpenSSHBootstrap -NativeHostArch $NativeHostArch -OneCore:$OneCore $PathTargets = Join-Path -Path $PSScriptRoot -ChildPath 'paths.targets' - if ($NoOpenSSL) - { + if ($NoOpenSSL) + { [XML]$xml = Get-Content $PathTargets $xml.Project.PropertyGroup.UseOpenSSL = 'false' $xml.Project.PropertyGroup.SSLLib = [string]::Empty @@ -523,11 +523,11 @@ function Start-OpenSSHBuild (Get-Content $f).Replace('#define OPENSSL_HAS_ECC 1','') | Set-Content $f (Get-Content $f).Replace('#define OPENSSL_HAS_NISTP521 1','') | Set-Content $f } - + $win10SDKVer = Get-Windows10SDKVersion [XML]$xml = Get-Content $PathTargets $xml.Project.PropertyGroup.WindowsSDKVersion = $win10SDKVer.ToString() - + if($NativeHostArch.ToLower().Startswith('arm')) { $arch = $NativeHostArch.ToUpper() @@ -538,7 +538,7 @@ function Start-OpenSSHBuild $newElement =$xml.CreateElement($nodeName, $xml.Project.xmlns) $newNode = $xml.Project.PropertyGroup.AppendChild($newElement) $null = $newNode.AppendChild($xml.CreateTextNode("true")) - } + } else { $node.InnerText = "true" @@ -553,18 +553,18 @@ function Start-OpenSSHBuild $xml.Project.PropertyGroup.WindowsSDKVersion = $win10SDKVer $xml.Project.PropertyGroup.AdditionalDependentLibs = 'onecore.lib;shlwapi.lib' $xml.Project.PropertyGroup.MinimalCoreWin = 'true' - + #Use onecore libcrypto binaries $xml.Project.PropertyGroup."LibreSSL-x86-Path" = '$(SolutionDir)\LibreSSL\bin\onecore\x86\' $xml.Project.PropertyGroup."LibreSSL-x64-Path" = '$(SolutionDir)\LibreSSL\bin\onecore\x64\' $xml.Project.PropertyGroup."LibreSSL-arm-Path" = '$(SolutionDir)\LibreSSL\bin\onecore\arm\' $xml.Project.PropertyGroup."LibreSSL-arm64-Path" = '$(SolutionDir)\LibreSSL\bin\onecore\arm64\' - + $xml.Save($PathTargets) } - + $solutionFile = Get-SolutionFile -root $repositoryRoot.FullName - $cmdMsg = @("${solutionFile}", "/t:Rebuild", "/p:Platform=${NativeHostArch}", "/p:Configuration=${Configuration}", "/m", "/nologo", "/fl", "/flp:LogFile=${script:BuildLogFile}`;Append`;Verbosity=diagnostic") + $cmdMsg = @("${solutionFile}", "/t:Rebuild", "/p:Platform=${NativeHostArch}", "/p:Configuration=${Configuration}", "/m", "/nologo", "/fl", "/flp:LogFile=${script:BuildLogFile}`;Append`;Verbosity=diagnostic") if($silent) { $cmdMsg += "/noconlog" @@ -588,7 +588,7 @@ function Start-OpenSSHBuild if ($errorCode -ne 0) { Write-BuildMsg -AsError -ErrorAction Stop -Message "Build failed for OpenSSH.`nExitCode: $errorCode." - } + } Write-BuildMsg -AsInfo -Message "SSH build successful." } @@ -683,13 +683,13 @@ function Get-BuildToolPath if (-not (Test-Path($buildToolsPath))) { Write-BuildMsg -AsError -ErrorAction Stop -Message "$packageName installation failed with error code $LASTEXITCODE." - } - } + } + } return $buildToolsPath } function Get-Windows10SDKVersion -{ +{ ## Search for latest windows sdk available on the machine $windowsSDKPath = Join-Path ${env:ProgramFiles(x86)} "Windows Kits\10\Lib" $minSDKVersion = [version]"10.0.17763.0" @@ -719,7 +719,7 @@ function Get-BuildLogFile [ValidateSet('x86', 'x64', 'arm64', 'arm')] [string]$NativeHostArch = "x64", - + [ValidateSet('Debug', 'Release')] [string]$Configuration = "Release" ) @@ -738,7 +738,7 @@ function Get-SolutionFile [Parameter(Mandatory=$true)] [ValidateNotNull()] [System.IO.DirectoryInfo] $root - ) + ) if ($root.FullName -ieq $PSScriptRoot) { return Join-Path -Path $PSScriptRoot -ChildPath "Win32-OpenSSH.sln" @@ -761,7 +761,7 @@ function Get-Chocolatey { } $machinePath = [Environment]::GetEnvironmentVariable('Path', 'MACHINE') - $newMachineEnvironmentPath = $machinePath + $newMachineEnvironmentPath = $machinePath if (-not ($machinePath.ToLower().Contains($chocolateyPath.ToLower()))) { @@ -781,7 +781,7 @@ function Get-Chocolatey { if ($newMachineEnvironmentPath -ne $machinePath) { [Environment]::SetEnvironmentVariable('Path', $newMachineEnvironmentPath, 'MACHINE') - } + } } Export-ModuleMember -Function Start-OpenSSHBuild, Get-BuildLogFile, Start-OpenSSHPackage, Copy-OpenSSHUnitTests diff --git a/contrib/win32/openssh/Win32-OpenSSH.sln b/contrib/win32/openssh/Win32-OpenSSH.sln index 4d54fd11685..fde6b4f0235 100644 --- a/contrib/win32/openssh/Win32-OpenSSH.sln +++ b/contrib/win32/openssh/Win32-OpenSSH.sln @@ -188,6 +188,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sshd-session", "sshd-sessio {DD483F7D-C553-4740-BC1A-903805AD0174} = {DD483F7D-C553-4740-BC1A-903805AD0174} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sshd-auth", "sshd-auth.vcxproj", "{4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}" + ProjectSection(ProjectDependencies) = postProject + {05E1115F-8529-46D0-AAAF-52A404CE79A7} = {05E1115F-8529-46D0-AAAF-52A404CE79A7} + {0D02F0F0-013B-4EE3-906D-86517F3822C0} = {0D02F0F0-013B-4EE3-906D-86517F3822C0} + {8F9D3B74-8D33-448E-9762-26E8DCC6B2F4} = {8F9D3B74-8D33-448E-9762-26E8DCC6B2F4} + {DD483F7D-C553-4740-BC1A-903805AD0174} = {DD483F7D-C553-4740-BC1A-903805AD0174} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -600,6 +608,22 @@ Global {86D5F580-EFB0-4BEA-96B7-7181F9BC6171}.Release|x64.Build.0 = Release|x64 {86D5F580-EFB0-4BEA-96B7-7181F9BC6171}.Release|x86.ActiveCfg = Release|Win32 {86D5F580-EFB0-4BEA-96B7-7181F9BC6171}.Release|x86.Build.0 = Release|Win32 + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Debug|ARM.ActiveCfg = Debug|ARM + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Debug|ARM.Build.0 = Debug|ARM + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Debug|ARM64.Build.0 = Debug|ARM64 + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Debug|x64.ActiveCfg = Debug|x64 + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Debug|x64.Build.0 = Debug|x64 + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Debug|x86.ActiveCfg = Debug|Win32 + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Debug|x86.Build.0 = Debug|Win32 + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Release|ARM.ActiveCfg = Release|ARM + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Release|ARM.Build.0 = Release|ARM + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Release|ARM64.ActiveCfg = Release|ARM64 + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Release|ARM64.Build.0 = Release|ARM64 + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Release|x64.ActiveCfg = Release|x64 + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Release|x64.Build.0 = Release|x64 + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Release|x86.ActiveCfg = Release|Win32 + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -630,6 +654,7 @@ Global {7D0A75FC-F366-4B60-B72F-B37C3EA07CCB} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E} {21D772C3-0EB0-47B7-A93C-FF624675A58D} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E} {86D5F580-EFB0-4BEA-96B7-7181F9BC6171} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E} + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE} = {17322AAF-808F-4646-AD37-5B0EDDCB8F3E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {0AC224E8-C215-4270-954A-A2ACEE06DE58} diff --git a/contrib/win32/openssh/libssh.vcxproj b/contrib/win32/openssh/libssh.vcxproj index 063660fe693..9a62332ad0a 100644 --- a/contrib/win32/openssh/libssh.vcxproj +++ b/contrib/win32/openssh/libssh.vcxproj @@ -438,7 +438,6 @@ - @@ -451,6 +450,7 @@ + diff --git a/contrib/win32/openssh/libssh.vcxproj.filters b/contrib/win32/openssh/libssh.vcxproj.filters index 349019a9347..05b2f5d18e2 100644 --- a/contrib/win32/openssh/libssh.vcxproj.filters +++ b/contrib/win32/openssh/libssh.vcxproj.filters @@ -57,7 +57,6 @@ - @@ -81,6 +80,7 @@ + @@ -146,12 +146,6 @@ Source Files - - Source Files - - - Source Files - Source Files @@ -206,9 +200,6 @@ Source Files - - Source Files - Source Files diff --git a/contrib/win32/openssh/sshd-auth.vcxproj b/contrib/win32/openssh/sshd-auth.vcxproj new file mode 100644 index 00000000000..c92c4fa12b8 --- /dev/null +++ b/contrib/win32/openssh/sshd-auth.vcxproj @@ -0,0 +1,486 @@ + + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {4FCA47E8-90E8-440F-A1C5-1E07CCCA89CE} + Win32Proj + keygen + $(WindowsSDKVersion) + sshd-auth + + + + Application + true + v143 + MultiByte + Spectre + + + Application + false + v143 + true + MultiByte + Spectre + + + Application + true + v143 + MultiByte + Spectre + + + Application + true + v143 + MultiByte + Spectre + + + Application + true + v143 + MultiByte + Spectre + + + Application + false + v143 + true + MultiByte + Spectre + + + Application + false + v143 + true + MultiByte + Spectre + + + Application + false + v143 + true + MultiByte + Spectre + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(TargetName)\ + $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + true + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(TargetName)\ + $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + true + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(TargetName)\ + $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + true + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(TargetName)\ + $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + false + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(TargetName)\ + $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + false + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(TargetName)\ + $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + false + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(TargetName)\ + $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + false + $(OpenSSH-Bin-Path)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\$(TargetName)\ + $(OpenSSH-Src-Path)contrib\win32\win32compat\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath); + + + + + + Level1 + Disabled + _CRT_DECLARE_NONSTDC_NAMES=0;_WIN32_WINNT=0x601;;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + false + $(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories) + MultiThreadedDebug + ProgramDatabase + Guard + /Gy /ZH:SHA_256 %(AdditionalOptions) + + + Console + true + posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies) + $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x86-Path);$(ZLib-x86-Path);%(AdditionalLibraryDirectories) + MultiplyDefinedSymbolOnly + wmainCRTStartup + NotSet + /debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 /ignore:4098 /CETCOMPAT %(AdditionalOptions) + + + targetos.manifest + + + + + + + Level1 + Disabled + _CRT_DECLARE_NONSTDC_NAMES=0;_WIN32_WINNT=0x601;;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + false + $(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories) + MultiThreadedDebug + ProgramDatabase + Guard + /Gy /ZH:SHA_256 %(AdditionalOptions) + + + Console + true + posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies) + $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x64-Path);$(ZLib-x64-Path);%(AdditionalLibraryDirectories) + MultiplyDefinedSymbolOnly + wmainCRTStartup + NotSet + /debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 /ignore:4098 /CETCOMPAT %(AdditionalOptions) + + + targetos.manifest + + + + + + + Level1 + Disabled + _CRT_DECLARE_NONSTDC_NAMES=0;_WIN32_WINNT=0x601;;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + false + $(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories) + MultiThreadedDebug + ProgramDatabase + Guard + /Gy /ZH:SHA_256 %(AdditionalOptions) + + + Console + true + posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies) + $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-arm64-Path);$(ZLib-arm64-Path);%(AdditionalLibraryDirectories) + MultiplyDefinedSymbolOnly + wmainCRTStartup + NotSet + /debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 /ignore:4098 %(AdditionalOptions) + + + targetos.manifest + + + + + + + Level1 + Disabled + _CRT_DECLARE_NONSTDC_NAMES=0;_WIN32_WINNT=0x601;;WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;%(PreprocessorDefinitions) + false + $(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories) + MultiThreadedDebug + ProgramDatabase + Guard + /Gy /ZH:SHA_256 %(AdditionalOptions) + + + Console + true + posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies) + $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-arm-Path);$(ZLib-arm-Path);%(AdditionalLibraryDirectories) + MultiplyDefinedSymbolOnly + wmainCRTStartup + NotSet + /debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 /ignore:4098 %(AdditionalOptions) + + + targetos.manifest + + + + + Level1 + + + MaxSpeed + true + true + _CRT_DECLARE_NONSTDC_NAMES=0;_WIN32_WINNT=0x601;;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories) + MultiThreaded + Guard + /Gy /ZH:SHA_256 %(AdditionalOptions) + + + Console + true + true + true + posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies) + $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x86-Path);$(ZLib-x86-Path);%(AdditionalLibraryDirectories) + MultiplyDefinedSymbolOnly + wmainCRTStartup + true + NotSet + /debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 /CETCOMPAT %(AdditionalOptions) + + + targetos.manifest + + + + + Level1 + + + MaxSpeed + true + true + _CRT_DECLARE_NONSTDC_NAMES=0;_WIN32_WINNT=0x601;;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories) + MultiThreaded + true + Guard + /Gy /ZH:SHA_256 %(AdditionalOptions) + + + Console + true + true + true + posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies) + $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-x64-Path);$(ZLib-x64-Path);%(AdditionalLibraryDirectories) + MultiplyDefinedSymbolOnly + wmainCRTStartup + true + NotSet + /debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 /CETCOMPAT %(AdditionalOptions) + + + targetos.manifest + + + + + Level1 + + + MaxSpeed + true + true + _CRT_DECLARE_NONSTDC_NAMES=0;_WIN32_WINNT=0x601;;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories) + MultiThreaded + true + Guard + /Gy /ZH:SHA_256 %(AdditionalOptions) + + + Console + true + true + true + posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies) + $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-arm64-Path);$(ZLib-arm64-Path);%(AdditionalLibraryDirectories) + MultiplyDefinedSymbolOnly + wmainCRTStartup + true + NotSet + /debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 %(AdditionalOptions) + + + targetos.manifest + + + + + Level1 + + + MaxSpeed + true + true + _CRT_DECLARE_NONSTDC_NAMES=0;_WIN32_WINNT=0x601;;_LIB;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SolutionDir);$(LibreSSL-Path)include;$(ZLib-Path);$(OpenSSH-Src-Path)includes;$(OpenSSH-Src-Path);$(OpenSSH-Src-Path)contrib\win32\win32compat;$(OpenSSH-Src-Path)libkrb;$(OpenSSH-Src-Path)libkrb\libKrb5;%(AdditionalIncludeDirectories) + MultiThreaded + true + Guard + /Gy /ZH:SHA_256 %(AdditionalOptions) + + + Console + true + true + true + posix_compat.lib;libssh.lib;openbsd_compat.lib;zlib.lib;$(SSLLib)$(AdditionalDependentLibs);%(AdditionalDependencies) + $(OpenSSH-Lib-Path)$(Platform)\$(Configuration);$(LibreSSL-arm-Path);$(ZLib-arm-Path);%(AdditionalLibraryDirectories) + MultiplyDefinedSymbolOnly + wmainCRTStartup + true + NotSet + /debug /debugtype:cv,fixup /opt:ref /opt:icf /incremental:no /ignore:4099 %(AdditionalOptions) + + + targetos.manifest + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/contrib/win32/openssh/sshd-auth.vcxproj.filters b/contrib/win32/openssh/sshd-auth.vcxproj.filters new file mode 100644 index 00000000000..92c12f29bce --- /dev/null +++ b/contrib/win32/openssh/sshd-auth.vcxproj.filters @@ -0,0 +1,173 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + + + Header Files + + + \ No newline at end of file diff --git a/contrib/win32/openssh/sshd-session.vcxproj b/contrib/win32/openssh/sshd-session.vcxproj index 7f759dcecf6..a4357e8f16d 100644 --- a/contrib/win32/openssh/sshd-session.vcxproj +++ b/contrib/win32/openssh/sshd-session.vcxproj @@ -456,7 +456,6 @@ - @@ -469,6 +468,7 @@ + diff --git a/contrib/win32/openssh/sshd-session.vcxproj.filters b/contrib/win32/openssh/sshd-session.vcxproj.filters index 3143b4a10c0..7924762f89a 100644 --- a/contrib/win32/openssh/sshd-session.vcxproj.filters +++ b/contrib/win32/openssh/sshd-session.vcxproj.filters @@ -108,9 +108,6 @@ Source Files - - Source Files - Source Files @@ -162,6 +159,9 @@ Source Files + + Source Files + diff --git a/contrib/win32/openssh/sshd.vcxproj b/contrib/win32/openssh/sshd.vcxproj index 7a5d07ddc1a..4828eb7060f 100644 --- a/contrib/win32/openssh/sshd.vcxproj +++ b/contrib/win32/openssh/sshd.vcxproj @@ -437,7 +437,6 @@ - diff --git a/contrib/win32/openssh/sshd.vcxproj.filters b/contrib/win32/openssh/sshd.vcxproj.filters index 186473c3c95..8729a88f8a9 100644 --- a/contrib/win32/openssh/sshd.vcxproj.filters +++ b/contrib/win32/openssh/sshd.vcxproj.filters @@ -51,9 +51,6 @@ Source Files - - Source Files - Source Files diff --git a/contrib/win32/openssh/version.rc b/contrib/win32/openssh/version.rc index 562cb8991ca..6436c00e398 100644 --- a/contrib/win32/openssh/version.rc +++ b/contrib/win32/openssh/version.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 9,8,3,0 - PRODUCTVERSION 9,8,3,0 + FILEVERSION 10,0,0,0 + PRODUCTVERSION 10,0,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -67,9 +67,9 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "FileVersion", "9.8.3.0" + VALUE "FileVersion", "10.0.0.0" VALUE "ProductName", "OpenSSH for Windows" - VALUE "ProductVersion", "OpenSSH_9.8p2 for Windows" + VALUE "ProductVersion", "OpenSSH_10.0p2 for Windows" END END BLOCK "VarFileInfo" diff --git a/contrib/win32/win32compat/inc/sys/time.h b/contrib/win32/win32compat/inc/sys/time.h index 21088bceef4..a0c5c41a646 100644 --- a/contrib/win32/win32compat/inc/sys/time.h +++ b/contrib/win32/win32compat/inc/sys/time.h @@ -11,6 +11,13 @@ struct timeval long tv_usec; }; +struct itimerval { + struct timeval it_interval; /* Timer interval */ + struct timeval it_value; /* Current value */ +}; + +#define ITIMER_REAL 0 + int usleep(unsigned int); int gettimeofday(struct timeval *, void *); int nanosleep(const struct timespec *, struct timespec *); diff --git a/contrib/win32/win32compat/inc/unistd.h b/contrib/win32/win32compat/inc/unistd.h index 85d9a6c2435..dc45d159631 100644 --- a/contrib/win32/win32compat/inc/unistd.h +++ b/contrib/win32/win32compat/inc/unistd.h @@ -49,6 +49,9 @@ int w32_dup2(int oldfd, int newfd); unsigned int w32_alarm(unsigned int seconds); #define alarm w32_alarm +int w32_setitimer(int which, const struct itimerval* new_value, struct itimerval* old_value); +#define setitimer w32_setitimer + long w32_lseek(int fd, unsigned __int64 offset, int origin); #define lseek w32_lseek diff --git a/contrib/win32/win32compat/signal.c b/contrib/win32/win32compat/signal.c index 0ac65ae9e00..f61cdd882d8 100644 --- a/contrib/win32/win32compat/signal.c +++ b/contrib/win32/win32compat/signal.c @@ -324,7 +324,7 @@ sw_initialize() /* * This is a minimal implementation of sigaction. * This is added to retrieve the current signal handler without actually setting the new signal handler, unlike w32_signal. - * The child process doesn't inherit the signal hanlders. + * The child process doesn't inherit the signal handlers. */ int sigaction(int signum, const struct sigaction * act, struct sigaction * oldact) diff --git a/contrib/win32/win32compat/signal_internal.h b/contrib/win32/win32compat/signal_internal.h index e60caf02933..44dcfd73826 100644 --- a/contrib/win32/win32compat/signal_internal.h +++ b/contrib/win32/win32compat/signal_internal.h @@ -32,6 +32,7 @@ struct _timer_info { ULONGLONG ticks_at_start; /* 0 if timer is not live */ __int64 run_time_sec; /* time in seconds, timer is set to go off from ticks_at_start */ }; + int sw_init_timer(); #define MAXIMUM_WAIT_OBJECTS_ENHANCED 1024 diff --git a/contrib/win32/win32compat/signal_sigalrm.c b/contrib/win32/win32compat/signal_sigalrm.c index c3a1836e3b7..3bd058145a9 100644 --- a/contrib/win32/win32compat/signal_sigalrm.c +++ b/contrib/win32/win32compat/signal_sigalrm.c @@ -29,6 +29,7 @@ */ #include "signal_internal.h" +#include "inc\sys\time.h" #include "inc\signal.h" #include "debug.h" @@ -64,8 +65,8 @@ w32_alarm(unsigned int sec) due.QuadPart *= sec; /* this call resets the timer if it is already active */ if (!SetWaitableTimer(timer_info.timer, &due, 0, sigalrm_APC, NULL, FALSE)) { - debug3("alram() - ERROR SetWaitableTimer() %d", GetLastError()); - return 0;; + debug3("alarm() - ERROR SetWaitableTimer() %d", GetLastError()); + return 0; } /* if timer was already ative, return when it was due */ @@ -80,6 +81,23 @@ w32_alarm(unsigned int sec) return ret; } +int w32_setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value) +{ + if (which != ITIMER_REAL) { + errno = EINVAL; + return -1; + } + if (old_value != NULL) { + errno = EINVAL; + return -1; + } + if (new_value->it_value.tv_sec == 0 && new_value->it_value.tv_usec == 0) { + w32_alarm(0); + return 0; + } + return w32_alarm(new_value->it_value.tv_sec); +} + int sw_init_timer() { diff --git a/contrib/win32/win32compat/w32fd.c b/contrib/win32/win32compat/w32fd.c index 308f30a949e..524e8c6b339 100644 --- a/contrib/win32/win32compat/w32fd.c +++ b/contrib/win32/win32compat/w32fd.c @@ -1084,7 +1084,7 @@ spawn_child_internal(const char* cmd, char *const argv[], HANDLE in, HANDLE out, si.hStdError = err; si.dwFlags = STARTF_USESTDHANDLES; - if (strstr(cmd, "sshd-session.exe")) { + if (strstr(cmd, "sshd-session.exe") || strstr(cmd, "sshd-auth.exe")) { flags |= DETACHED_PROCESS; } diff --git a/contrib/win32/win32compat/wmain_sshd-auth.c b/contrib/win32/win32compat/wmain_sshd-auth.c new file mode 100644 index 00000000000..0080ea9c178 --- /dev/null +++ b/contrib/win32/win32compat/wmain_sshd-auth.c @@ -0,0 +1,115 @@ +/* +* Author: Manoj Ampalam +* +* wmain entry for sshd-session. +* +* Copyright (c) 2015 Microsoft Corp. +* All rights reserved +* +* Microsoft openssh win32 port +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. 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. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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. +*/ + +/* disable inclusion of compatability defitnitions in CRT headers */ +#define __STDC__ 1 +#include +#include +#include +#include +#include + +#include "inc\utf.h" +#include "misc_internal.h" +#include "Debug.h" + +int main(int, char **); +extern HANDLE main_thread; + +int sshd_session_main(int argc, wchar_t **wargv) { + char** argv = NULL; + int i, r; + _set_invalid_parameter_handler(invalid_parameter_handler); + + if ((argv = malloc((argc + 1) * sizeof(char*))) == NULL) + fatal("out of memory"); + + for (i = 0; i < argc; i++) + if ((argv[i] = utf16_to_utf8(wargv[i])) == NULL) + fatal("out of memory"); + argv[argc] = NULL; + + w32posix_initialize(); + + r = main(argc, argv); + w32posix_done(); + return r; +} + +int argc_original = 0; +wchar_t **wargv_original = NULL; + +int wmain(int argc, wchar_t **wargv) { + wchar_t *path_value = NULL, *path_new_value; + errno_t result = 0; + size_t path_new_len = 0, len; + argc_original = argc; + wargv_original = wargv; + + init_prog_paths(); + /* change current directory to sshd-session.exe root */ + _wchdir(__wprogdir); + + /* + * we want to launch scp and sftp executables from the binary directory + * that sshd is hosted in. This will facilitate hosting and evaluating + * multiple versions of OpenSSH at the same time. + * it does not work well for powershell, cygwin, etc if program path is + * prepended to executable directory. + * To achive above, PATH is set to process environment + */ + _wdupenv_s(&path_value, &len, L"PATH"); + if (!path_value || (wcsstr(path_value, __wprogdir)) == NULL) { + path_new_len = wcslen(__wprogdir) + wcslen(path_value) + 2; + if ((path_new_value = (wchar_t *) malloc(path_new_len * sizeof(wchar_t))) == NULL) { + errno = ENOMEM; + error("failed to allocation memory"); + return -1; + } + swprintf_s(path_new_value, path_new_len, L"%s%s%s", __wprogdir, path_value ? L";" : L"", path_value); + if (result = _wputenv_s(L"PATH", path_new_value)) { + error("failed to set PATH environment variable: to value:%s, error:%d", path_new_value, result); + errno = result; + if (path_new_value) + free(path_new_value); + if(path_value) + free(path_value); + return -1; + } + if (path_new_value) + free(path_new_value); + if(path_value) + free(path_value); + } + + return sshd_session_main(argc, wargv); +} diff --git a/crypto_api.h b/crypto_api.h index 5d552ef0237..8bbc3a08aae 100644 --- a/crypto_api.h +++ b/crypto_api.h @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto_api.h,v 1.8 2023/01/15 23:05:32 djm Exp $ */ +/* $OpenBSD: crypto_api.h,v 1.9 2024/09/02 12:13:56 djm Exp $ */ /* * Assembled from generated headers and source files by Markus Friedl. @@ -53,4 +53,9 @@ int crypto_kem_sntrup761_dec(unsigned char *k, const unsigned char *cstr, const unsigned char *sk); int crypto_kem_sntrup761_keypair(unsigned char *pk, unsigned char *sk); +#define crypto_kem_mlkem768_PUBLICKEYBYTES 1184 +#define crypto_kem_mlkem768_SECRETKEYBYTES 2400 +#define crypto_kem_mlkem768_CIPHERTEXTBYTES 1088 +#define crypto_kem_mlkem768_BYTES 32 + #endif /* crypto_api_h */ diff --git a/defines.h b/defines.h index 279e509aae2..d2baeb9407b 100644 --- a/defines.h +++ b/defines.h @@ -216,7 +216,9 @@ including rpc/rpc.h breaks Solaris 6 /* (or die trying) */ #ifndef HAVE_U_INT +typedef unsigned short u_short; typedef unsigned int u_int; +typedef unsigned long u_long; #endif #ifndef HAVE_INTXX_T @@ -646,6 +648,46 @@ struct winsize { # endif /* WORDS_BIGENDIAN */ #endif /* BYTE_ORDER */ +#if (defined(HAVE_DECL_LE32TOH) && HAVE_DECL_LE32TOH == 0) || \ + (defined(HAVE_DECL_LE64TOH) && HAVE_DECL_LE64TOH == 0) || \ + (defined(HAVE_DECL_HTOLE64) && HAVE_DECL_HTOLE64 == 0) +# define openssh_swap32(v) \ + (uint32_t)(((uint32_t)(v) & 0xff) << 24 | \ + ((uint32_t)(v) & 0xff00) << 8 | \ + ((uint32_t)(v) & 0xff0000) >> 8 | \ + ((uint32_t)(v) & 0xff000000) >> 24) +# define openssh_swap64(v) \ + (uint64_t)((((uint64_t)(v) & 0xff) << 56) | \ + ((uint64_t)(v) & 0xff00ULL) << 40 | \ + ((uint64_t)(v) & 0xff0000ULL) << 24 | \ + ((uint64_t)(v) & 0xff000000ULL) << 8 | \ + ((uint64_t)(v) & 0xff00000000ULL) >> 8 | \ + ((uint64_t)(v) & 0xff0000000000ULL) >> 24 | \ + ((uint64_t)(v) & 0xff000000000000ULL) >> 40 | \ + ((uint64_t)(v) & 0xff00000000000000ULL) >> 56) +# ifdef WORDS_BIGENDIAN +# if defined(HAVE_DECL_LE32TOH) && HAVE_DECL_LE32TOH == 0 +# define le32toh(v) (openssh_swap32(v)) +# endif +# if defined(HAVE_DECL_LE64TOH) && HAVE_DECL_LE64TOH == 0 +# define le64toh(v) (openssh_swap64(v)) +# endif +# if defined(HAVE_DECL_HTOLE64) && HAVE_DECL_HTOLE64 == 0 +# define htole64(v) (openssh_swap64(v)) +# endif +# else +# if defined(HAVE_DECL_LE32TOH) && HAVE_DECL_LE32TOH == 0 +# define le32toh(v) ((uint32_t)v) +# endif +# if defined(HAVE_DECL_LE64TOH) && HAVE_DECL_LE64TOH == 0 +# define le64toh(v) ((uint64_t)v) +# endif +# if defined(HAVE_DECL_HTOLE64) && HAVE_DECL_HTOLE64 == 0 +# define htole64(v) ((uint64_t)v) +# endif +# endif +#endif + /* Function replacement / compatibility hacks */ #if !defined(HAVE_GETADDRINFO) && (defined(HAVE_OGETADDRINFO) || defined(HAVE_NGETADDRINFO)) @@ -940,6 +982,8 @@ struct winsize { * so only enable if the compiler supports them. */ #if defined(VARIABLE_LENGTH_ARRAYS) && defined(VARIABLE_DECLARATION_AFTER_CODE) -# define USE_SNTRUP761X25519 1 +# define USE_SNTRUP761X25519 1 +/* The ML-KEM768 implementation also uses C89 features */ +# define USE_MLKEM768X25519 1 #endif #endif /* _DEFINES_H */ diff --git a/dh.c b/dh.c index f32495381ed..345feeec48a 100644 --- a/dh.c +++ b/dh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dh.c,v 1.74 2021/04/03 06:18:40 djm Exp $ */ +/* $OpenBSD: dh.c,v 1.75 2024/12/03 16:27:53 dtucker Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * @@ -241,9 +241,9 @@ choose_dh(int min, int wantbits, int max) if (bestcount == 0) { fclose(f); - logit("WARNING: no suitable primes in %s", - get_moduli_filename()); - return (dh_new_group_fallback(max)); + logit("WARNING: no suitable primes (size %d/%d/%d) in %s", + min, wantbits, max, get_moduli_filename()); + return NULL; } which = arc4random_uniform(bestcount); diff --git a/groupaccess.c b/groupaccess.c index 80d3019152c..9d03ded0cd5 100644 --- a/groupaccess.c +++ b/groupaccess.c @@ -1,4 +1,4 @@ -/* $OpenBSD: groupaccess.c,v 1.17 2019/03/06 22:14:23 dtucker Exp $ */ +/* $OpenBSD: groupaccess.c,v 1.18 2024/11/04 21:59:15 jca Exp $ */ /* * Copyright (c) 2001 Kevin Steves. All rights reserved. * diff --git a/gss-serv.c b/gss-serv.c index ff91354854d..0dd35752a40 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -29,6 +29,7 @@ #ifdef GSSAPI #include +#include #include #include diff --git a/includes.h b/includes.h index 6d17ef6da93..8f933568d33 100644 --- a/includes.h +++ b/includes.h @@ -49,6 +49,9 @@ #ifdef HAVE_PATHS_H # include #endif +#ifdef HAVE_FCNTL_H +# include /* For AT_FDCWD */ +#endif /* *-*-nto-qnx needs these headers for strcasecmp and LASTLOG_FILE respectively diff --git a/kex-names.c b/kex-names.c index 339eb1c23cc..ec840c1f9db 100644 --- a/kex-names.c +++ b/kex-names.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex-names.c,v 1.1 2024/05/17 00:32:32 djm Exp $ */ +/* $OpenBSD: kex-names.c,v 1.4 2024/09/09 02:39:57 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -79,6 +79,12 @@ static const struct kexalg kexalgs[] = { #ifdef USE_SNTRUP761X25519 { KEX_SNTRUP761X25519_SHA512, KEX_KEM_SNTRUP761X25519_SHA512, 0, SSH_DIGEST_SHA512 }, + { KEX_SNTRUP761X25519_SHA512_OLD, KEX_KEM_SNTRUP761X25519_SHA512, 0, + SSH_DIGEST_SHA512 }, +#endif +#ifdef USE_MLKEM768X25519 + { KEX_MLKEM768X25519_SHA256, KEX_KEM_MLKEM768X25519_SHA256, 0, + SSH_DIGEST_SHA256 }, #endif #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ { NULL, 0, -1, -1}, diff --git a/kex.c b/kex.c index e8d534047d3..1e70f66d59a 100644 --- a/kex.c +++ b/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.186 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: kex.c,v 1.187 2024/08/23 04:51:00 deraadt Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -850,8 +850,6 @@ choose_comp(struct sshcomp *comp, char *client, char *server) #ifdef WITH_ZLIB if (strcmp(name, "zlib@openssh.com") == 0) { comp->type = COMP_DELAYED; - } else if (strcmp(name, "zlib") == 0) { - comp->type = COMP_ZLIB; } else #endif /* WITH_ZLIB */ if (strcmp(name, "none") == 0) { diff --git a/kex.h b/kex.h index 34665eb20ce..d08988b3e14 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.123 2024/05/17 00:30:23 djm Exp $ */ +/* $OpenBSD: kex.h,v 1.126 2024/09/02 12:13:56 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -62,11 +62,11 @@ #define KEX_ECDH_SHA2_NISTP521 "ecdh-sha2-nistp521" #define KEX_CURVE25519_SHA256 "curve25519-sha256" #define KEX_CURVE25519_SHA256_OLD "curve25519-sha256@libssh.org" -#define KEX_SNTRUP761X25519_SHA512 "sntrup761x25519-sha512@openssh.com" +#define KEX_SNTRUP761X25519_SHA512 "sntrup761x25519-sha512" +#define KEX_SNTRUP761X25519_SHA512_OLD "sntrup761x25519-sha512@openssh.com" +#define KEX_MLKEM768X25519_SHA256 "mlkem768x25519-sha256" #define COMP_NONE 0 -/* pre-auth compression (COMP_ZLIB) is only supported in the client */ -#define COMP_ZLIB 1 #define COMP_DELAYED 2 #define CURVE25519_SIZE 32 @@ -102,6 +102,7 @@ enum kex_exchange { KEX_ECDH_SHA2, KEX_C25519_SHA256, KEX_KEM_SNTRUP761X25519_SHA512, + KEX_KEM_MLKEM768X25519_SHA256, KEX_MAX }; @@ -180,6 +181,7 @@ struct kex { u_char c25519_client_key[CURVE25519_SIZE]; /* 25519 + KEM */ u_char c25519_client_pubkey[CURVE25519_SIZE]; /* 25519 */ u_char sntrup761_client_key[crypto_kem_sntrup761_SECRETKEYBYTES]; /* KEM */ + u_char mlkem768_client_key[crypto_kem_mlkem768_SECRETKEYBYTES]; /* KEM */ struct sshbuf *client_pub; }; @@ -246,6 +248,12 @@ int kex_kem_sntrup761x25519_enc(struct kex *, const struct sshbuf *, int kex_kem_sntrup761x25519_dec(struct kex *, const struct sshbuf *, struct sshbuf **); +int kex_kem_mlkem768x25519_keypair(struct kex *); +int kex_kem_mlkem768x25519_enc(struct kex *, const struct sshbuf *, + struct sshbuf **, struct sshbuf **); +int kex_kem_mlkem768x25519_dec(struct kex *, const struct sshbuf *, + struct sshbuf **); + int kex_dh_keygen(struct kex *); int kex_dh_compute_key(struct kex *, BIGNUM *, struct sshbuf *); diff --git a/kexc25519.c b/kexc25519.c index 44cd1ff3f18..9df17e3aea3 100644 --- a/kexc25519.c +++ b/kexc25519.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexc25519.c,v 1.17 2019/01/21 10:40:11 djm Exp $ */ +/* $OpenBSD: kexc25519.c,v 1.18 2024/09/02 12:13:56 djm Exp $ */ /* * Copyright (c) 2019 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -71,7 +71,7 @@ kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE], return SSH_ERR_KEY_INVALID_EC_VALUE; #ifdef DEBUG_KEXECDH - dump_digest("shared secret", shared_key, CURVE25519_SIZE); + dump_digest("shared secret 25519", shared_key, CURVE25519_SIZE); #endif if (raw) r = sshbuf_put(out, shared_key, CURVE25519_SIZE); diff --git a/kexgen.c b/kexgen.c index 20f3c57110a..40d688d62fd 100644 --- a/kexgen.c +++ b/kexgen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgen.c,v 1.8 2021/12/19 22:08:06 djm Exp $ */ +/* $OpenBSD: kexgen.c,v 1.10 2024/09/09 02:39:57 djm Exp $ */ /* * Copyright (c) 2019 Markus Friedl. All rights reserved. * @@ -120,6 +120,9 @@ kex_gen_client(struct ssh *ssh) case KEX_KEM_SNTRUP761X25519_SHA512: r = kex_kem_sntrup761x25519_keypair(kex); break; + case KEX_KEM_MLKEM768X25519_SHA256: + r = kex_kem_mlkem768x25519_keypair(kex); + break; default: r = SSH_ERR_INVALID_ARGUMENT; break; @@ -192,6 +195,10 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh) r = kex_kem_sntrup761x25519_dec(kex, server_blob, &shared_secret); break; + case KEX_KEM_MLKEM768X25519_SHA256: + r = kex_kem_mlkem768x25519_dec(kex, server_blob, + &shared_secret); + break; default: r = SSH_ERR_INVALID_ARGUMENT; break; @@ -243,6 +250,8 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh) explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key)); explicit_bzero(kex->sntrup761_client_key, sizeof(kex->sntrup761_client_key)); + explicit_bzero(kex->mlkem768_client_key, + sizeof(kex->mlkem768_client_key)); sshbuf_free(server_host_key_blob); free(signature); sshbuf_free(tmp); @@ -310,6 +319,10 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh) r = kex_kem_sntrup761x25519_enc(kex, client_pubkey, &server_pubkey, &shared_secret); break; + case KEX_KEM_MLKEM768X25519_SHA256: + r = kex_kem_mlkem768x25519_enc(kex, client_pubkey, + &server_pubkey, &shared_secret); + break; default: r = SSH_ERR_INVALID_ARGUMENT; break; diff --git a/kexmlkem768x25519.c b/kexmlkem768x25519.c new file mode 100644 index 00000000000..2b5d3960823 --- /dev/null +++ b/kexmlkem768x25519.c @@ -0,0 +1,283 @@ +/* $OpenBSD: kexmlkem768x25519.c,v 1.2 2024/10/27 02:06:59 djm Exp $ */ +/* + * Copyright (c) 2023 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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. + */ + +#include "includes.h" + +#include + +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include +#include +#include +#ifdef HAVE_ENDIAN_H +# include +#endif + +#include "sshkey.h" +#include "kex.h" +#include "sshbuf.h" +#include "digest.h" +#include "ssherr.h" +#include "log.h" + +#ifdef USE_MLKEM768X25519 + +#include "libcrux_mlkem768_sha3.h" + +int +kex_kem_mlkem768x25519_keypair(struct kex *kex) +{ + struct sshbuf *buf = NULL; + u_char rnd[LIBCRUX_ML_KEM_KEY_PAIR_PRNG_LEN], *cp = NULL; + size_t need; + int r = SSH_ERR_INTERNAL_ERROR; + struct libcrux_mlkem768_keypair keypair; + + if ((buf = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + need = crypto_kem_mlkem768_PUBLICKEYBYTES + CURVE25519_SIZE; + if ((r = sshbuf_reserve(buf, need, &cp)) != 0) + goto out; + arc4random_buf(rnd, sizeof(rnd)); + keypair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(rnd); + memcpy(cp, keypair.pk.value, crypto_kem_mlkem768_PUBLICKEYBYTES); + memcpy(kex->mlkem768_client_key, keypair.sk.value, + sizeof(kex->mlkem768_client_key)); +#ifdef DEBUG_KEXECDH + dump_digest("client public key mlkem768:", cp, + crypto_kem_mlkem768_PUBLICKEYBYTES); +#endif + cp += crypto_kem_mlkem768_PUBLICKEYBYTES; + kexc25519_keygen(kex->c25519_client_key, cp); +#ifdef DEBUG_KEXECDH + dump_digest("client public key c25519:", cp, CURVE25519_SIZE); +#endif + /* success */ + r = 0; + kex->client_pub = buf; + buf = NULL; + out: + explicit_bzero(&keypair, sizeof(keypair)); + explicit_bzero(rnd, sizeof(rnd)); + sshbuf_free(buf); + return r; +} + +int +kex_kem_mlkem768x25519_enc(struct kex *kex, + const struct sshbuf *client_blob, struct sshbuf **server_blobp, + struct sshbuf **shared_secretp) +{ + struct sshbuf *server_blob = NULL; + struct sshbuf *buf = NULL; + const u_char *client_pub; + u_char rnd[LIBCRUX_ML_KEM_ENC_PRNG_LEN]; + u_char server_pub[CURVE25519_SIZE], server_key[CURVE25519_SIZE]; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t need; + int r = SSH_ERR_INTERNAL_ERROR; + struct libcrux_mlkem768_enc_result enc; + struct libcrux_mlkem768_pk mlkem_pub; + + *server_blobp = NULL; + *shared_secretp = NULL; + memset(&mlkem_pub, 0, sizeof(mlkem_pub)); + + /* client_blob contains both KEM and ECDH client pubkeys */ + need = crypto_kem_mlkem768_PUBLICKEYBYTES + CURVE25519_SIZE; + if (sshbuf_len(client_blob) != need) { + r = SSH_ERR_SIGNATURE_INVALID; + goto out; + } + client_pub = sshbuf_ptr(client_blob); +#ifdef DEBUG_KEXECDH + dump_digest("client public key mlkem768:", client_pub, + crypto_kem_mlkem768_PUBLICKEYBYTES); + dump_digest("client public key 25519:", + client_pub + crypto_kem_mlkem768_PUBLICKEYBYTES, + CURVE25519_SIZE); +#endif + /* check public key validity */ + memcpy(mlkem_pub.value, client_pub, crypto_kem_mlkem768_PUBLICKEYBYTES); + if (!libcrux_ml_kem_mlkem768_portable_validate_public_key(&mlkem_pub)) { + r = SSH_ERR_SIGNATURE_INVALID; + goto out; + } + + /* allocate buffer for concatenation of KEM key and ECDH shared key */ + /* the buffer will be hashed and the result is the shared secret */ + if ((buf = sshbuf_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + /* allocate space for encrypted KEM key and ECDH pub key */ + if ((server_blob = sshbuf_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + /* generate and encrypt KEM key with client key */ + arc4random_buf(rnd, sizeof(rnd)); + enc = libcrux_ml_kem_mlkem768_portable_encapsulate(&mlkem_pub, rnd); + /* generate ECDH key pair, store server pubkey after ciphertext */ + kexc25519_keygen(server_key, server_pub); + if ((r = sshbuf_put(buf, enc.snd, sizeof(enc.snd))) != 0 || + (r = sshbuf_put(server_blob, enc.fst.value, sizeof(enc.fst.value))) != 0 || + (r = sshbuf_put(server_blob, server_pub, sizeof(server_pub))) != 0) + goto out; + /* append ECDH shared key */ + client_pub += crypto_kem_mlkem768_PUBLICKEYBYTES; + if ((r = kexc25519_shared_key_ext(server_key, client_pub, buf, 1)) < 0) + goto out; + if ((r = ssh_digest_buffer(kex->hash_alg, buf, hash, sizeof(hash))) != 0) + goto out; +#ifdef DEBUG_KEXECDH + dump_digest("server public key 25519:", server_pub, CURVE25519_SIZE); + dump_digest("server cipher text:", + enc.fst.value, sizeof(enc.fst.value)); + dump_digest("server kem key:", enc.snd, sizeof(enc.snd)); + dump_digest("concatenation of KEM key and ECDH shared key:", + sshbuf_ptr(buf), sshbuf_len(buf)); +#endif + /* string-encoded hash is resulting shared secret */ + sshbuf_reset(buf); + if ((r = sshbuf_put_string(buf, hash, + ssh_digest_bytes(kex->hash_alg))) != 0) + goto out; +#ifdef DEBUG_KEXECDH + dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf)); +#endif + /* success */ + r = 0; + *server_blobp = server_blob; + *shared_secretp = buf; + server_blob = NULL; + buf = NULL; + out: + explicit_bzero(hash, sizeof(hash)); + explicit_bzero(server_key, sizeof(server_key)); + explicit_bzero(rnd, sizeof(rnd)); + explicit_bzero(&enc, sizeof(enc)); + sshbuf_free(server_blob); + sshbuf_free(buf); + return r; +} + +int +kex_kem_mlkem768x25519_dec(struct kex *kex, + const struct sshbuf *server_blob, struct sshbuf **shared_secretp) +{ + struct sshbuf *buf = NULL; + u_char mlkem_key[crypto_kem_mlkem768_BYTES]; + const u_char *ciphertext, *server_pub; + u_char hash[SSH_DIGEST_MAX_LENGTH]; + size_t need; + int r; + struct libcrux_mlkem768_sk mlkem_priv; + struct libcrux_mlkem768_ciphertext mlkem_ciphertext; + + *shared_secretp = NULL; + memset(&mlkem_priv, 0, sizeof(mlkem_priv)); + memset(&mlkem_ciphertext, 0, sizeof(mlkem_ciphertext)); + + need = crypto_kem_mlkem768_CIPHERTEXTBYTES + CURVE25519_SIZE; + if (sshbuf_len(server_blob) != need) { + r = SSH_ERR_SIGNATURE_INVALID; + goto out; + } + ciphertext = sshbuf_ptr(server_blob); + server_pub = ciphertext + crypto_kem_mlkem768_CIPHERTEXTBYTES; + /* hash concatenation of KEM key and ECDH shared key */ + if ((buf = sshbuf_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + memcpy(mlkem_priv.value, kex->mlkem768_client_key, + sizeof(kex->mlkem768_client_key)); + memcpy(mlkem_ciphertext.value, ciphertext, + sizeof(mlkem_ciphertext.value)); +#ifdef DEBUG_KEXECDH + dump_digest("server cipher text:", mlkem_ciphertext.value, + sizeof(mlkem_ciphertext.value)); + dump_digest("server public key c25519:", server_pub, CURVE25519_SIZE); +#endif + libcrux_ml_kem_mlkem768_portable_decapsulate(&mlkem_priv, + &mlkem_ciphertext, mlkem_key); + if ((r = sshbuf_put(buf, mlkem_key, sizeof(mlkem_key))) != 0) + goto out; + if ((r = kexc25519_shared_key_ext(kex->c25519_client_key, server_pub, + buf, 1)) < 0) + goto out; + if ((r = ssh_digest_buffer(kex->hash_alg, buf, + hash, sizeof(hash))) != 0) + goto out; +#ifdef DEBUG_KEXECDH + dump_digest("client kem key:", mlkem_key, sizeof(mlkem_key)); + dump_digest("concatenation of KEM key and ECDH shared key:", + sshbuf_ptr(buf), sshbuf_len(buf)); +#endif + sshbuf_reset(buf); + if ((r = sshbuf_put_string(buf, hash, + ssh_digest_bytes(kex->hash_alg))) != 0) + goto out; +#ifdef DEBUG_KEXECDH + dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf)); +#endif + /* success */ + r = 0; + *shared_secretp = buf; + buf = NULL; + out: + explicit_bzero(hash, sizeof(hash)); + explicit_bzero(&mlkem_priv, sizeof(mlkem_priv)); + explicit_bzero(&mlkem_ciphertext, sizeof(mlkem_ciphertext)); + explicit_bzero(mlkem_key, sizeof(mlkem_key)); + sshbuf_free(buf); + return r; +} +#else /* USE_MLKEM768X25519 */ +int +kex_kem_mlkem768x25519_keypair(struct kex *kex) +{ + return SSH_ERR_SIGN_ALG_UNSUPPORTED; +} + +int +kex_kem_mlkem768x25519_enc(struct kex *kex, + const struct sshbuf *client_blob, struct sshbuf **server_blobp, + struct sshbuf **shared_secretp) +{ + return SSH_ERR_SIGN_ALG_UNSUPPORTED; +} + +int +kex_kem_mlkem768x25519_dec(struct kex *kex, + const struct sshbuf *server_blob, struct sshbuf **shared_secretp) +{ + return SSH_ERR_SIGN_ALG_UNSUPPORTED; +} +#endif /* USE_MLKEM768X25519 */ diff --git a/kexsntrup761x25519.c b/kexsntrup761x25519.c index 6afb1bad560..6bbca71fcef 100644 --- a/kexsntrup761x25519.c +++ b/kexsntrup761x25519.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexsntrup761x25519.c,v 1.2 2021/12/05 12:28:27 jsg Exp $ */ +/* $OpenBSD: kexsntrup761x25519.c,v 1.3 2024/09/15 02:20:51 djm Exp $ */ /* * Copyright (c) 2019 Markus Friedl. All rights reserved. * @@ -39,6 +39,10 @@ #include "digest.h" #include "ssherr.h" +volatile crypto_int16 crypto_int16_optblocker = 0; +volatile crypto_int32 crypto_int32_optblocker = 0; +volatile crypto_int64 crypto_int64_optblocker = 0; + int kex_kem_sntrup761x25519_keypair(struct kex *kex) { diff --git a/libcrux_mlkem768_sha3.h b/libcrux_mlkem768_sha3.h new file mode 100644 index 00000000000..885e82bafa0 --- /dev/null +++ b/libcrux_mlkem768_sha3.h @@ -0,0 +1,12338 @@ +/* $OpenBSD: libcrux_mlkem768_sha3.h,v 1.2 2024/10/27 02:06:01 djm Exp $ */ + +/* Extracted from libcrux revision 84c5d87b3092c59294345aa269ceefe0eb97cc35 */ + +/* + * MIT License + * + * Copyright (c) 2024 Cryspen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if !defined(__GNUC__) || (__GNUC__ < 2) +# define __attribute__(x) +#endif +#define KRML_MUSTINLINE inline +#define KRML_NOINLINE __attribute__((noinline, unused)) +#define KRML_HOST_EPRINTF(...) +#define KRML_HOST_EXIT(x) fatal_f("internal error") + +/* from libcrux/libcrux-ml-kem/cg/eurydice_glue.h */ +/* + * SPDX-FileCopyrightText: 2024 Eurydice Contributors + * SPDX-FileCopyrightText: 2024 Cryspen Sarl + * + * SPDX-License-Identifier: MIT or Apache-2.0 + */ + +#pragma once + +#if defined(__cplusplus) +extern "C" { +#endif + + + +// SLICES, ARRAYS, ETC. + +// The MSVC C++ compiler does not support compound literals. +// This CLITERAL is used to turn `(type){...}` into `type{...}` when using a C++ +// compiler. +#if defined(__cplusplus) +#define CLITERAL(type) type +#else +#define CLITERAL(type) (type) +#endif + +// We represent a slice as a pair of an (untyped) pointer, along with the length +// of the slice, i.e. the number of elements in the slice (this is NOT the +// number of bytes). This design choice has two important consequences. +// - if you need to use `ptr`, you MUST cast it to a proper type *before* +// performing pointer +// arithmetic on it (remember that C desugars pointer arithmetic based on the +// type of the address) +// - if you need to use `len` for a C style function (e.g. memcpy, memcmp), you +// need to multiply it +// by sizeof t, where t is the type of the elements. +// +// Empty slices have `len == 0` and `ptr` always needs to be valid pointer that +// is not NULL (otherwise the construction in EURYDICE_SLICE computes `NULL + +// start`). +typedef struct { + void *ptr; + size_t len; +} Eurydice_slice; + +// Helper macro to create a slice out of a pointer x, a start index in x +// (included), and an end index in x (excluded). The argument x must be suitably +// cast to something that can decay (see remark above about how pointer +// arithmetic works in C), meaning either pointer or array type. +#define EURYDICE_SLICE(x, start, end) \ + (CLITERAL(Eurydice_slice){.ptr = (void *)(x + start), .len = end - start}) +#define EURYDICE_SLICE_LEN(s, _) s.len +// This macro is a pain because in case the dereferenced element type is an +// array, you cannot simply write `t x` as it would yield `int[4] x` instead, +// which is NOT correct C syntax, so we add a dedicated phase in Eurydice that +// adds an extra argument to this macro at the last minute so that we have the +// correct type of *pointers* to elements. +#define Eurydice_slice_index(s, i, t, t_ptr_t) (((t_ptr_t)s.ptr)[i]) +#define Eurydice_slice_subslice(s, r, t, _) \ + EURYDICE_SLICE((t *)s.ptr, r.start, r.end) +// Variant for when the start and end indices are statically known (i.e., the +// range argument `r` is a literal). +#define Eurydice_slice_subslice2(s, start, end, t) \ + EURYDICE_SLICE((t *)s.ptr, start, end) +#define Eurydice_slice_subslice_to(s, subslice_end_pos, t, _) \ + EURYDICE_SLICE((t *)s.ptr, 0, subslice_end_pos) +#define Eurydice_slice_subslice_from(s, subslice_start_pos, t, _) \ + EURYDICE_SLICE((t *)s.ptr, subslice_start_pos, s.len) +#define Eurydice_array_to_slice(end, x, t) \ + EURYDICE_SLICE(x, 0, \ + end) /* x is already at an array type, no need for cast */ +#define Eurydice_array_to_subslice(_arraylen, x, r, t, _) \ + EURYDICE_SLICE((t *)x, r.start, r.end) +// Same as above, variant for when start and end are statically known +#define Eurydice_array_to_subslice2(x, start, end, t) \ + EURYDICE_SLICE((t *)x, start, end) +#define Eurydice_array_to_subslice_to(_size, x, r, t, _range_t) \ + EURYDICE_SLICE((t *)x, 0, r) +#define Eurydice_array_to_subslice_from(size, x, r, t, _range_t) \ + EURYDICE_SLICE((t *)x, r, size) +#define Eurydice_slice_len(s, t) EURYDICE_SLICE_LEN(s, t) +#define Eurydice_slice_copy(dst, src, t) \ + memcpy(dst.ptr, src.ptr, dst.len * sizeof(t)) +#define core_array___Array_T__N__23__as_slice(len_, ptr_, t, _ret_t) \ + ((Eurydice_slice){.ptr = ptr_, .len = len_}) + +#define core_array___core__clone__Clone_for__Array_T__N___20__clone( \ + len, src, dst, elem_type, _ret_t) \ + (memcpy(dst, src, len * sizeof(elem_type))) +#define TryFromSliceError uint8_t + +#define Eurydice_array_eq(sz, a1, a2, t, _) \ + (memcmp(a1, a2, sz * sizeof(t)) == 0) +#define core_array_equality___core__cmp__PartialEq__Array_U__N___for__Array_T__N____eq( \ + sz, a1, a2, t, _, _ret_t) \ + Eurydice_array_eq(sz, a1, a2, t, _) +#define core_array_equality___core__cmp__PartialEq__0___Slice_U____for__Array_T__N___3__eq( \ + sz, a1, a2, t, _, _ret_t) \ + Eurydice_array_eq(sz, a1, ((a2)->ptr), t, _) + +#define Eurydice_slice_split_at(slice, mid, element_type, ret_t) \ + (CLITERAL(ret_t){ \ + .fst = EURYDICE_SLICE((element_type *)slice.ptr, 0, mid), \ + .snd = EURYDICE_SLICE((element_type *)slice.ptr, mid, slice.len)}) +#define Eurydice_slice_split_at_mut(slice, mid, element_type, ret_t) \ + (CLITERAL(ret_t){ \ + .fst = {.ptr = slice.ptr, .len = mid}, \ + .snd = {.ptr = (char *)slice.ptr + mid * sizeof(element_type), \ + .len = slice.len - mid}}) + +// Conversion of slice to an array, rewritten (by Eurydice) to name the +// destination array, since arrays are not values in C. +// N.B.: see note in karamel/lib/Inlining.ml if you change this. +#define Eurydice_slice_to_array2(dst, src, _, t_arr) \ + Eurydice_slice_to_array3(&(dst)->tag, (char *)&(dst)->val.case_Ok, src, \ + sizeof(t_arr)) + +static inline void Eurydice_slice_to_array3(uint8_t *dst_tag, char *dst_ok, + Eurydice_slice src, size_t sz) { + *dst_tag = 0; + memcpy(dst_ok, src.ptr, sz); +} + +// CORE STUFF (conversions, endianness, ...) + +static inline void core_num__u64_9__to_le_bytes(uint64_t v, uint8_t buf[8]) { + v = htole64(v); + memcpy(buf, &v, sizeof(v)); +} +static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t buf[8]) { + uint64_t v; + memcpy(&v, buf, sizeof(v)); + return le64toh(v); +} + +static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t buf[4]) { + uint32_t v; + memcpy(&v, buf, sizeof(v)); + return le32toh(v); +} + +static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) { +#if defined(_MSC_VER) + return __popcnt(x0); +#elif !defined(MISSING_BUILTIN_POPCOUNT) + return __builtin_popcount(x0); +#else + const uint8_t v[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + return v[x0 & 0xf] + v[(x0 >> 4) & 0xf]; + +#endif +} + +// unsigned overflow wraparound semantics in C +static inline uint16_t core_num__u16_7__wrapping_add(uint16_t x, uint16_t y) { + return x + y; +} +static inline uint8_t core_num__u8_6__wrapping_sub(uint8_t x, uint8_t y) { + return x - y; +} + +// ITERATORS + +#define Eurydice_range_iter_next(iter_ptr, t, ret_t) \ + (((iter_ptr)->start == (iter_ptr)->end) \ + ? (CLITERAL(ret_t){.tag = None}) \ + : (CLITERAL(ret_t){.tag = Some, .f0 = (iter_ptr)->start++})) + +#define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next \ + Eurydice_range_iter_next + +// See note in karamel/lib/Inlining.ml if you change this +#define Eurydice_into_iter(x, t, _ret_t) (x) +#define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter \ + Eurydice_into_iter + +#if defined(__cplusplus) +} +#endif + +/* from libcrux/libcrux-ml-kem/cg/libcrux_core.h */ +/* + * SPDX-FileCopyrightText: 2024 Cryspen Sarl + * + * SPDX-License-Identifier: MIT or Apache-2.0 + * + * This code was generated with the following revisions: + * Charon: 6b5e110342a771a3e1c739b10294b1778e4be8b4 + * Eurydice: 31be7d65ca5d6acdacfb33652e478d24dd85c1cb + * Karamel: 3205d3365ea2790b02368f79fcee38e38d0b5908 + * F*: a32b316e521fa4f239b610ec8f1d15e78d62cbe8-dirty + * Libcrux: 4ad532b206174114dd4140b718e7794a28fc59ee + */ + +#ifndef __libcrux_core_H +#define __libcrux_core_H + +#if defined(__cplusplus) +extern "C" { +#endif + + +/** +A monomorphic instance of core.ops.range.Range +with types size_t + +*/ +typedef struct core_ops_range_Range_b3_s { + size_t start; + size_t end; +} core_ops_range_Range_b3; + +#define Ok 0 +#define Err 1 + +typedef uint8_t Result_86_tags; + +#define None 0 +#define Some 1 + +typedef uint8_t Option_ef_tags; + +/** +A monomorphic instance of core.option.Option +with types size_t + +*/ +typedef struct Option_b3_s { + Option_ef_tags tag; + size_t f0; +} Option_b3; + +static inline uint16_t core_num__u16_7__wrapping_add(uint16_t x0, uint16_t x1); + +#define CORE_NUM__U32_8__BITS (32U) + +static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t x0[8U]); + +static inline void core_num__u64_9__to_le_bytes(uint64_t x0, uint8_t x1[8U]); + +static inline uint32_t core_num__u8_6__count_ones(uint8_t x0); + +static inline uint8_t core_num__u8_6__wrapping_sub(uint8_t x0, uint8_t x1); + +#define LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE ((size_t)32U) + +#define LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT ((size_t)12U) + +#define LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT ((size_t)256U) + +#define LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * (size_t)12U) + +#define LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT \ + (LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE ((size_t)32U) + +#define LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE ((size_t)32U) + +typedef struct libcrux_ml_kem_utils_extraction_helper_Keypair768_s { + uint8_t fst[1152U]; + uint8_t snd[1184U]; +} libcrux_ml_kem_utils_extraction_helper_Keypair768; + +/** +A monomorphic instance of core.result.Result +with types uint8_t[24size_t], core_array_TryFromSliceError + +*/ +typedef struct Result_6f_s { + Result_86_tags tag; + union { + uint8_t case_Ok[24U]; + TryFromSliceError case_Err; + } val; +} Result_6f; + +/** +This function found in impl {core::result::Result} +*/ +/** +A monomorphic instance of core.result.unwrap_41 +with types uint8_t[24size_t], core_array_TryFromSliceError + +*/ +static inline void unwrap_41_1c(Result_6f self, uint8_t ret[24U]) { + if (self.tag == Ok) { + uint8_t f0[24U]; + memcpy(f0, self.val.case_Ok, (size_t)24U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)24U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +/** +A monomorphic instance of core.result.Result +with types uint8_t[20size_t], core_array_TryFromSliceError + +*/ +typedef struct Result_7a_s { + Result_86_tags tag; + union { + uint8_t case_Ok[20U]; + TryFromSliceError case_Err; + } val; +} Result_7a; + +/** +This function found in impl {core::result::Result} +*/ +/** +A monomorphic instance of core.result.unwrap_41 +with types uint8_t[20size_t], core_array_TryFromSliceError + +*/ +static inline void unwrap_41_34(Result_7a self, uint8_t ret[20U]) { + if (self.tag == Ok) { + uint8_t f0[20U]; + memcpy(f0, self.val.case_Ok, (size_t)20U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)20U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +/** +A monomorphic instance of core.result.Result +with types uint8_t[10size_t], core_array_TryFromSliceError + +*/ +typedef struct Result_cd_s { + Result_86_tags tag; + union { + uint8_t case_Ok[10U]; + TryFromSliceError case_Err; + } val; +} Result_cd; + +/** +This function found in impl {core::result::Result} +*/ +/** +A monomorphic instance of core.result.unwrap_41 +with types uint8_t[10size_t], core_array_TryFromSliceError + +*/ +static inline void unwrap_41_e8(Result_cd self, uint8_t ret[10U]) { + if (self.tag == Ok) { + uint8_t f0[10U]; + memcpy(f0, self.val.case_Ok, (size_t)10U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)10U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +typedef struct Eurydice_slice_uint8_t_4size_t__x2_s { + Eurydice_slice fst[4U]; + Eurydice_slice snd[4U]; +} Eurydice_slice_uint8_t_4size_t__x2; + +typedef struct libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s { + uint8_t value[1088U]; +} libcrux_ml_kem_mlkem768_MlKem768Ciphertext; + +/** + A reference to the raw byte slice. +*/ +/** +This function found in impl {libcrux_ml_kem::types::MlKemCiphertext#6} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.as_slice_d4 +with const generics +- SIZE= 1088 +*/ +static inline uint8_t *libcrux_ml_kem_types_as_slice_d4_1d( + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self) { + return self->value; +} + +/** +A monomorphic instance of libcrux_ml_kem.types.MlKemPublicKey +with const generics +- $1184size_t +*/ +typedef struct libcrux_ml_kem_types_MlKemPublicKey_15_s { + uint8_t value[1184U]; +} libcrux_ml_kem_types_MlKemPublicKey_15; + +/** +This function found in impl {(core::convert::From<@Array> for +libcrux_ml_kem::types::MlKemPublicKey)#14} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_b6 +with const generics +- SIZE= 1184 +*/ +static inline libcrux_ml_kem_types_MlKemPublicKey_15 +libcrux_ml_kem_types_from_b6_da(uint8_t value[1184U]) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_value[1184U]; + memcpy(copy_of_value, value, (size_t)1184U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPublicKey_15 lit; + memcpy(lit.value, copy_of_value, (size_t)1184U * sizeof(uint8_t)); + return lit; +} + +/** +A monomorphic instance of libcrux_ml_kem.types.MlKemPrivateKey +with const generics +- $2400size_t +*/ +typedef struct libcrux_ml_kem_types_MlKemPrivateKey_55_s { + uint8_t value[2400U]; +} libcrux_ml_kem_types_MlKemPrivateKey_55; + +typedef struct libcrux_ml_kem_mlkem768_MlKem768KeyPair_s { + libcrux_ml_kem_types_MlKemPrivateKey_55 sk; + libcrux_ml_kem_types_MlKemPublicKey_15 pk; +} libcrux_ml_kem_mlkem768_MlKem768KeyPair; + +/** + Create a new [`MlKemKeyPair`] from the secret and public key. +*/ +/** +This function found in impl +{libcrux_ml_kem::types::MlKemKeyPair} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_17 +with const generics +- PRIVATE_KEY_SIZE= 2400 +- PUBLIC_KEY_SIZE= 1184 +*/ +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_types_from_17_35(libcrux_ml_kem_types_MlKemPrivateKey_55 sk, + libcrux_ml_kem_types_MlKemPublicKey_15 pk) { + return ( + CLITERAL(libcrux_ml_kem_mlkem768_MlKem768KeyPair){.sk = sk, .pk = pk}); +} + +/** +This function found in impl {(core::convert::From<@Array> for +libcrux_ml_kem::types::MlKemPrivateKey)#8} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_05 +with const generics +- SIZE= 2400 +*/ +static inline libcrux_ml_kem_types_MlKemPrivateKey_55 +libcrux_ml_kem_types_from_05_f2(uint8_t value[2400U]) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_value[2400U]; + memcpy(copy_of_value, value, (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey_55 lit; + memcpy(lit.value, copy_of_value, (size_t)2400U * sizeof(uint8_t)); + return lit; +} + +/** +A monomorphic instance of core.result.Result +with types uint8_t[32size_t], core_array_TryFromSliceError + +*/ +typedef struct Result_00_s { + Result_86_tags tag; + union { + uint8_t case_Ok[32U]; + TryFromSliceError case_Err; + } val; +} Result_00; + +/** +This function found in impl {core::result::Result} +*/ +/** +A monomorphic instance of core.result.unwrap_41 +with types uint8_t[32size_t], core_array_TryFromSliceError + +*/ +static inline void unwrap_41_83(Result_00 self, uint8_t ret[32U]) { + if (self.tag == Ok) { + uint8_t f0[32U]; + memcpy(f0, self.val.case_Ok, (size_t)32U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)32U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +/** +A monomorphic instance of K. +with types libcrux_ml_kem_types_MlKemCiphertext[[$1088size_t]], +uint8_t[32size_t] + +*/ +typedef struct tuple_3c_s { + libcrux_ml_kem_mlkem768_MlKem768Ciphertext fst; + uint8_t snd[32U]; +} tuple_3c; + +/** +This function found in impl {(core::convert::From<@Array> for +libcrux_ml_kem::types::MlKemCiphertext)#2} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.from_01 +with const generics +- SIZE= 1088 +*/ +static inline libcrux_ml_kem_mlkem768_MlKem768Ciphertext +libcrux_ml_kem_types_from_01_9f(uint8_t value[1088U]) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_value[1088U]; + memcpy(copy_of_value, value, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext lit; + memcpy(lit.value, copy_of_value, (size_t)1088U * sizeof(uint8_t)); + return lit; +} + +/** + A reference to the raw byte slice. +*/ +/** +This function found in impl {libcrux_ml_kem::types::MlKemPublicKey#18} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.as_slice_cb +with const generics +- SIZE= 1184 +*/ +static inline uint8_t *libcrux_ml_kem_types_as_slice_cb_50( + libcrux_ml_kem_types_MlKemPublicKey_15 *self) { + return self->value; +} + +/** + Pad the `slice` with `0`s at the end. +*/ +/** +A monomorphic instance of libcrux_ml_kem.utils.into_padded_array +with const generics +- LEN= 33 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_ea2( + Eurydice_slice slice, uint8_t ret[33U]) { + uint8_t out[33U] = {0U}; + uint8_t *uu____0 = out; + Eurydice_slice_copy( + Eurydice_array_to_subslice2(uu____0, (size_t)0U, + Eurydice_slice_len(slice, uint8_t), uint8_t), + slice, uint8_t); + memcpy(ret, out, (size_t)33U * sizeof(uint8_t)); +} + +/** + Pad the `slice` with `0`s at the end. +*/ +/** +A monomorphic instance of libcrux_ml_kem.utils.into_padded_array +with const generics +- LEN= 34 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_ea1( + Eurydice_slice slice, uint8_t ret[34U]) { + uint8_t out[34U] = {0U}; + uint8_t *uu____0 = out; + Eurydice_slice_copy( + Eurydice_array_to_subslice2(uu____0, (size_t)0U, + Eurydice_slice_len(slice, uint8_t), uint8_t), + slice, uint8_t); + memcpy(ret, out, (size_t)34U * sizeof(uint8_t)); +} + +/** +This function found in impl {(core::convert::AsRef<@Slice> for +libcrux_ml_kem::types::MlKemCiphertext)#1} +*/ +/** +A monomorphic instance of libcrux_ml_kem.types.as_ref_00 +with const generics +- SIZE= 1088 +*/ +static inline Eurydice_slice libcrux_ml_kem_types_as_ref_00_24( + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *self) { + return Eurydice_array_to_slice((size_t)1088U, self->value, uint8_t); +} + +/** + Pad the `slice` with `0`s at the end. +*/ +/** +A monomorphic instance of libcrux_ml_kem.utils.into_padded_array +with const generics +- LEN= 1120 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_ea0( + Eurydice_slice slice, uint8_t ret[1120U]) { + uint8_t out[1120U] = {0U}; + uint8_t *uu____0 = out; + Eurydice_slice_copy( + Eurydice_array_to_subslice2(uu____0, (size_t)0U, + Eurydice_slice_len(slice, uint8_t), uint8_t), + slice, uint8_t); + memcpy(ret, out, (size_t)1120U * sizeof(uint8_t)); +} + +/** + Pad the `slice` with `0`s at the end. +*/ +/** +A monomorphic instance of libcrux_ml_kem.utils.into_padded_array +with const generics +- LEN= 64 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_utils_into_padded_array_ea( + Eurydice_slice slice, uint8_t ret[64U]) { + uint8_t out[64U] = {0U}; + uint8_t *uu____0 = out; + Eurydice_slice_copy( + Eurydice_array_to_subslice2(uu____0, (size_t)0U, + Eurydice_slice_len(slice, uint8_t), uint8_t), + slice, uint8_t); + memcpy(ret, out, (size_t)64U * sizeof(uint8_t)); +} + +/** +A monomorphic instance of core.result.Result +with types int16_t[16size_t], core_array_TryFromSliceError + +*/ +typedef struct Result_c0_s { + Result_86_tags tag; + union { + int16_t case_Ok[16U]; + TryFromSliceError case_Err; + } val; +} Result_c0; + +/** +This function found in impl {core::result::Result} +*/ +/** +A monomorphic instance of core.result.unwrap_41 +with types int16_t[16size_t], core_array_TryFromSliceError + +*/ +static inline void unwrap_41_f9(Result_c0 self, int16_t ret[16U]) { + if (self.tag == Ok) { + int16_t f0[16U]; + memcpy(f0, self.val.case_Ok, (size_t)16U * sizeof(int16_t)); + memcpy(ret, f0, (size_t)16U * sizeof(int16_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +/** +A monomorphic instance of core.result.Result +with types uint8_t[8size_t], core_array_TryFromSliceError + +*/ +typedef struct Result_56_s { + Result_86_tags tag; + union { + uint8_t case_Ok[8U]; + TryFromSliceError case_Err; + } val; +} Result_56; + +/** +This function found in impl {core::result::Result} +*/ +/** +A monomorphic instance of core.result.unwrap_41 +with types uint8_t[8size_t], core_array_TryFromSliceError + +*/ +static inline void unwrap_41_ac(Result_56 self, uint8_t ret[8U]) { + if (self.tag == Ok) { + uint8_t f0[8U]; + memcpy(f0, self.val.case_Ok, (size_t)8U * sizeof(uint8_t)); + memcpy(ret, f0, (size_t)8U * sizeof(uint8_t)); + } else { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "unwrap not Ok"); + KRML_HOST_EXIT(255U); + } +} + +typedef struct Eurydice_slice_uint8_t_x2_s { + Eurydice_slice fst; + Eurydice_slice snd; +} Eurydice_slice_uint8_t_x2; + +typedef struct Eurydice_slice_uint8_t_1size_t__x2_s { + Eurydice_slice fst[1U]; + Eurydice_slice snd[1U]; +} Eurydice_slice_uint8_t_1size_t__x2; + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_core_H_DEFINED +#endif + +/* from libcrux/libcrux-ml-kem/cg/libcrux_ct_ops.h */ +/* + * SPDX-FileCopyrightText: 2024 Cryspen Sarl + * + * SPDX-License-Identifier: MIT or Apache-2.0 + * + * This code was generated with the following revisions: + * Charon: 6b5e110342a771a3e1c739b10294b1778e4be8b4 + * Eurydice: 31be7d65ca5d6acdacfb33652e478d24dd85c1cb + * Karamel: 3205d3365ea2790b02368f79fcee38e38d0b5908 + * F*: a32b316e521fa4f239b610ec8f1d15e78d62cbe8-dirty + * Libcrux: 4ad532b206174114dd4140b718e7794a28fc59ee + */ + +#ifndef __libcrux_ct_ops_H +#define __libcrux_ct_ops_H + +#if defined(__cplusplus) +extern "C" { +#endif + + +/** + Return 1 if `value` is not zero and 0 otherwise. +*/ +static inline uint8_t libcrux_ml_kem_constant_time_ops_inz(uint8_t value) { + uint16_t value0 = (uint16_t)value; + uint16_t result = (((uint32_t)value0 | + (uint32_t)core_num__u16_7__wrapping_add(~value0, 1U)) & + 0xFFFFU) >> + 8U & + 1U; + return (uint8_t)result; +} + +static KRML_NOINLINE uint8_t +libcrux_ml_kem_constant_time_ops_is_non_zero(uint8_t value) { + return libcrux_ml_kem_constant_time_ops_inz(value); +} + +/** + Return 1 if the bytes of `lhs` and `rhs` do not exactly + match and 0 otherwise. +*/ +static inline uint8_t libcrux_ml_kem_constant_time_ops_compare( + Eurydice_slice lhs, Eurydice_slice rhs) { + uint8_t r = 0U; + for (size_t i = (size_t)0U; i < Eurydice_slice_len(lhs, uint8_t); i++) { + size_t i0 = i; + r = (uint32_t)r | + ((uint32_t)Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *) ^ + (uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *)); + } + return libcrux_ml_kem_constant_time_ops_is_non_zero(r); +} + +static KRML_NOINLINE uint8_t +libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time( + Eurydice_slice lhs, Eurydice_slice rhs) { + return libcrux_ml_kem_constant_time_ops_compare(lhs, rhs); +} + +/** + If `selector` is not zero, return the bytes in `rhs`; return the bytes in + `lhs` otherwise. +*/ +static inline void libcrux_ml_kem_constant_time_ops_select_ct( + Eurydice_slice lhs, Eurydice_slice rhs, uint8_t selector, + uint8_t ret[32U]) { + uint8_t mask = core_num__u8_6__wrapping_sub( + libcrux_ml_kem_constant_time_ops_is_non_zero(selector), 1U); + uint8_t out[32U] = {0U}; + for (size_t i = (size_t)0U; i < LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE; + i++) { + size_t i0 = i; + out[i0] = ((uint32_t)Eurydice_slice_index(lhs, i0, uint8_t, uint8_t *) & + (uint32_t)mask) | + ((uint32_t)Eurydice_slice_index(rhs, i0, uint8_t, uint8_t *) & + (uint32_t)~mask); + } + memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); +} + +static KRML_NOINLINE void +libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + Eurydice_slice lhs, Eurydice_slice rhs, uint8_t selector, + uint8_t ret[32U]) { + libcrux_ml_kem_constant_time_ops_select_ct(lhs, rhs, selector, ret); +} + +static inline void +libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( + Eurydice_slice lhs_c, Eurydice_slice rhs_c, Eurydice_slice lhs_s, + Eurydice_slice rhs_s, uint8_t ret[32U]) { + uint8_t selector = + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_in_constant_time( + lhs_c, rhs_c); + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_select_shared_secret_in_constant_time( + lhs_s, rhs_s, selector, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_ct_ops_H_DEFINED +#endif + +/* from libcrux/libcrux-ml-kem/cg/libcrux_sha3_portable.h */ +/* + * SPDX-FileCopyrightText: 2024 Cryspen Sarl + * + * SPDX-License-Identifier: MIT or Apache-2.0 + * + * This code was generated with the following revisions: + * Charon: 6b5e110342a771a3e1c739b10294b1778e4be8b4 + * Eurydice: 31be7d65ca5d6acdacfb33652e478d24dd85c1cb + * Karamel: 3205d3365ea2790b02368f79fcee38e38d0b5908 + * F*: a32b316e521fa4f239b610ec8f1d15e78d62cbe8-dirty + * Libcrux: 4ad532b206174114dd4140b718e7794a28fc59ee + */ + +#ifndef __libcrux_sha3_portable_H +#define __libcrux_sha3_portable_H + +#if defined(__cplusplus) +extern "C" { +#endif + + +static const uint64_t libcrux_sha3_generic_keccak_ROUNDCONSTANTS[24U] = { + 1ULL, + 32898ULL, + 9223372036854808714ULL, + 9223372039002292224ULL, + 32907ULL, + 2147483649ULL, + 9223372039002292353ULL, + 9223372036854808585ULL, + 138ULL, + 136ULL, + 2147516425ULL, + 2147483658ULL, + 2147516555ULL, + 9223372036854775947ULL, + 9223372036854808713ULL, + 9223372036854808579ULL, + 9223372036854808578ULL, + 9223372036854775936ULL, + 32778ULL, + 9223372039002259466ULL, + 9223372039002292353ULL, + 9223372036854808704ULL, + 2147483649ULL, + 9223372039002292232ULL}; + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +static KRML_MUSTINLINE uint64_t libcrux_sha3_portable_keccak_zero_5a(void) { + return 0ULL; +} + +static KRML_MUSTINLINE uint64_t libcrux_sha3_portable_keccak__veor5q_u64( + uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e) { + uint64_t ab = a ^ b; + uint64_t cd = c ^ d; + uint64_t abcd = ab ^ cd; + return abcd ^ e; +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +static KRML_MUSTINLINE uint64_t libcrux_sha3_portable_keccak_xor5_5a( + uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint64_t e) { + return libcrux_sha3_portable_keccak__veor5q_u64(a, b, c, d, e); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 1 +- RIGHT= 63 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb(uint64_t x) { + return x << (uint32_t)(int32_t)1 | x >> (uint32_t)(int32_t)63; +} + +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vrax1q_u64(uint64_t a, uint64_t b) { + uint64_t uu____0 = a; + return uu____0 ^ libcrux_sha3_portable_keccak_rotate_left_cb(b); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vrax1q_u64(a, b); +} + +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vbcaxq_u64(uint64_t a, uint64_t b, uint64_t c) { + return a ^ (b & ~c); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +static KRML_MUSTINLINE uint64_t libcrux_sha3_portable_keccak_and_not_xor_5a( + uint64_t a, uint64_t b, uint64_t c) { + return libcrux_sha3_portable_keccak__vbcaxq_u64(a, b, c); +} + +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__veorq_n_u64(uint64_t a, uint64_t c) { + return a ^ c; +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_constant_5a(uint64_t a, uint64_t c) { + return libcrux_sha3_portable_keccak__veorq_n_u64(a, c); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_5a(uint64_t a, uint64_t b) { + return a ^ b; +} + +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_slice_1( + Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) { + ret[0U] = Eurydice_slice_subslice2(a[0U], start, start + len, uint8_t); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_slice_n_5a( + Eurydice_slice a[1U], size_t start, size_t len, Eurydice_slice ret[1U]) { + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_a[1U]; + memcpy(copy_of_a, a, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret0[1U]; + libcrux_sha3_portable_keccak_slice_1(copy_of_a, start, len, ret0); + memcpy(ret, ret0, (size_t)1U * sizeof(Eurydice_slice)); +} + +static KRML_MUSTINLINE Eurydice_slice_uint8_t_1size_t__x2 +libcrux_sha3_portable_keccak_split_at_mut_1(Eurydice_slice out[1U], + size_t mid) { + Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at_mut( + out[0U], mid, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice out00 = uu____0.fst; + Eurydice_slice out01 = uu____0.snd; + Eurydice_slice_uint8_t_1size_t__x2 lit; + lit.fst[0U] = out00; + lit.snd[0U] = out01; + return lit; +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +static KRML_MUSTINLINE Eurydice_slice_uint8_t_1size_t__x2 +libcrux_sha3_portable_keccak_split_at_mut_n_5a(Eurydice_slice a[1U], + size_t mid) { + return libcrux_sha3_portable_keccak_split_at_mut_1(a, mid); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.KeccakState +with types uint64_t +with const generics +- $1size_t +*/ +typedef struct libcrux_sha3_generic_keccak_KeccakState_48_s { + uint64_t st[5U][5U]; +} libcrux_sha3_generic_keccak_KeccakState_48; + +/** + Create a new Shake128 x4 state. +*/ +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakState[TraitClause@0]#1} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.new_1e +with types uint64_t +with const generics +- N= 1 +*/ +static KRML_MUSTINLINE libcrux_sha3_generic_keccak_KeccakState_48 +libcrux_sha3_generic_keccak_new_1e_f4(void) { + libcrux_sha3_generic_keccak_KeccakState_48 lit; + lit.st[0U][0U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[0U][1U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[0U][2U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[0U][3U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[0U][4U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[1U][0U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[1U][1U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[1U][2U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[1U][3U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[1U][4U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[2U][0U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[2U][1U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[2U][2U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[2U][3U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[2U][4U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[3U][0U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[3U][1U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[3U][2U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[3U][3U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[3U][4U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[4U][0U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[4U][1U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[4U][2U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[4U][3U] = libcrux_sha3_portable_keccak_zero_5a(); + lit.st[4U][4U] = libcrux_sha3_portable_keccak_zero_5a(); + return lit; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block +with const generics +- RATE= 72 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) { + size_t i0 = i; + uint8_t uu____0[8U]; + Result_56 dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0, + (size_t)8U * i0 + (size_t)8U, uint8_t), + Eurydice_slice, uint8_t[8U]); + unwrap_41_ac(dst, uu____0); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = + s[uu____1][uu____2] ^ core_num__u64_9__from_le_bytes(uu____0); + } +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a +with const generics +- RATE= 72 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b8( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_b[1U]; + memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block_2c(uu____0, copy_of_b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 36 +- RIGHT= 28 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb0(uint64_t x) { + return x << (uint32_t)(int32_t)36 | x >> (uint32_t)(int32_t)28; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 36 +- RIGHT= 28 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_42(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb0(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 36 +- RIGHT= 28 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_42(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 3 +- RIGHT= 61 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb1(uint64_t x) { + return x << (uint32_t)(int32_t)3 | x >> (uint32_t)(int32_t)61; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 3 +- RIGHT= 61 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_420(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb1(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 3 +- RIGHT= 61 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb0(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_420(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 41 +- RIGHT= 23 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb2(uint64_t x) { + return x << (uint32_t)(int32_t)41 | x >> (uint32_t)(int32_t)23; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 41 +- RIGHT= 23 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_421(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb2(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 41 +- RIGHT= 23 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb1(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_421(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 18 +- RIGHT= 46 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb3(uint64_t x) { + return x << (uint32_t)(int32_t)18 | x >> (uint32_t)(int32_t)46; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 18 +- RIGHT= 46 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_422(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb3(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 18 +- RIGHT= 46 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb2(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_422(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 1 +- RIGHT= 63 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_423(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 1 +- RIGHT= 63 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb3(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_423(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 44 +- RIGHT= 20 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb4(uint64_t x) { + return x << (uint32_t)(int32_t)44 | x >> (uint32_t)(int32_t)20; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 44 +- RIGHT= 20 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_424(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb4(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 44 +- RIGHT= 20 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb4(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_424(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 10 +- RIGHT= 54 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb5(uint64_t x) { + return x << (uint32_t)(int32_t)10 | x >> (uint32_t)(int32_t)54; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 10 +- RIGHT= 54 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_425(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb5(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 10 +- RIGHT= 54 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb5(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_425(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 45 +- RIGHT= 19 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb6(uint64_t x) { + return x << (uint32_t)(int32_t)45 | x >> (uint32_t)(int32_t)19; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 45 +- RIGHT= 19 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_426(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb6(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 45 +- RIGHT= 19 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb6(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_426(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 2 +- RIGHT= 62 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb7(uint64_t x) { + return x << (uint32_t)(int32_t)2 | x >> (uint32_t)(int32_t)62; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 2 +- RIGHT= 62 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_427(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb7(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 2 +- RIGHT= 62 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb7(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_427(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 62 +- RIGHT= 2 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb8(uint64_t x) { + return x << (uint32_t)(int32_t)62 | x >> (uint32_t)(int32_t)2; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 62 +- RIGHT= 2 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_428(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb8(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 62 +- RIGHT= 2 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb8(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_428(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 6 +- RIGHT= 58 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb9(uint64_t x) { + return x << (uint32_t)(int32_t)6 | x >> (uint32_t)(int32_t)58; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 6 +- RIGHT= 58 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_429(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb9(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 6 +- RIGHT= 58 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb9(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_429(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 43 +- RIGHT= 21 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb10(uint64_t x) { + return x << (uint32_t)(int32_t)43 | x >> (uint32_t)(int32_t)21; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 43 +- RIGHT= 21 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_4210(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb10(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 43 +- RIGHT= 21 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb10(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_4210(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 15 +- RIGHT= 49 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb11(uint64_t x) { + return x << (uint32_t)(int32_t)15 | x >> (uint32_t)(int32_t)49; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 15 +- RIGHT= 49 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_4211(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb11(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 15 +- RIGHT= 49 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb11(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_4211(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 61 +- RIGHT= 3 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb12(uint64_t x) { + return x << (uint32_t)(int32_t)61 | x >> (uint32_t)(int32_t)3; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 61 +- RIGHT= 3 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_4212(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb12(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 61 +- RIGHT= 3 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb12(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_4212(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 28 +- RIGHT= 36 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb13(uint64_t x) { + return x << (uint32_t)(int32_t)28 | x >> (uint32_t)(int32_t)36; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 28 +- RIGHT= 36 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_4213(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb13(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 28 +- RIGHT= 36 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb13(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_4213(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 55 +- RIGHT= 9 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb14(uint64_t x) { + return x << (uint32_t)(int32_t)55 | x >> (uint32_t)(int32_t)9; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 55 +- RIGHT= 9 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_4214(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb14(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 55 +- RIGHT= 9 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb14(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_4214(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 25 +- RIGHT= 39 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb15(uint64_t x) { + return x << (uint32_t)(int32_t)25 | x >> (uint32_t)(int32_t)39; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 25 +- RIGHT= 39 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_4215(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb15(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 25 +- RIGHT= 39 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb15(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_4215(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 21 +- RIGHT= 43 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb16(uint64_t x) { + return x << (uint32_t)(int32_t)21 | x >> (uint32_t)(int32_t)43; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 21 +- RIGHT= 43 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_4216(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb16(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 21 +- RIGHT= 43 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb16(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_4216(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 56 +- RIGHT= 8 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb17(uint64_t x) { + return x << (uint32_t)(int32_t)56 | x >> (uint32_t)(int32_t)8; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 56 +- RIGHT= 8 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_4217(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb17(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 56 +- RIGHT= 8 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb17(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_4217(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 27 +- RIGHT= 37 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb18(uint64_t x) { + return x << (uint32_t)(int32_t)27 | x >> (uint32_t)(int32_t)37; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 27 +- RIGHT= 37 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_4218(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb18(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 27 +- RIGHT= 37 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb18(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_4218(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 20 +- RIGHT= 44 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb19(uint64_t x) { + return x << (uint32_t)(int32_t)20 | x >> (uint32_t)(int32_t)44; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 20 +- RIGHT= 44 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_4219(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb19(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 20 +- RIGHT= 44 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb19(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_4219(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 39 +- RIGHT= 25 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb20(uint64_t x) { + return x << (uint32_t)(int32_t)39 | x >> (uint32_t)(int32_t)25; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 39 +- RIGHT= 25 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_4220(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb20(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 39 +- RIGHT= 25 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb20(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_4220(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 8 +- RIGHT= 56 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb21(uint64_t x) { + return x << (uint32_t)(int32_t)8 | x >> (uint32_t)(int32_t)56; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 8 +- RIGHT= 56 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_4221(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb21(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 8 +- RIGHT= 56 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb21(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_4221(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.rotate_left +with const generics +- LEFT= 14 +- RIGHT= 50 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_rotate_left_cb22(uint64_t x) { + return x << (uint32_t)(int32_t)14 | x >> (uint32_t)(int32_t)50; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak._vxarq_u64 +with const generics +- LEFT= 14 +- RIGHT= 50 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak__vxarq_u64_4222(uint64_t a, uint64_t b) { + uint64_t ab = a ^ b; + return libcrux_sha3_portable_keccak_rotate_left_cb22(ab); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.xor_and_rotate_5a +with const generics +- LEFT= 14 +- RIGHT= 50 +*/ +static KRML_MUSTINLINE uint64_t +libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb22(uint64_t a, uint64_t b) { + return libcrux_sha3_portable_keccak__vxarq_u64_4222(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.theta_rho +with types uint64_t +with const generics +- N= 1 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_theta_rho_16( + libcrux_sha3_generic_keccak_KeccakState_48 *s) { + uint64_t c[5U] = { + libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][0U], s->st[1U][0U], + s->st[2U][0U], s->st[3U][0U], + s->st[4U][0U]), + libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][1U], s->st[1U][1U], + s->st[2U][1U], s->st[3U][1U], + s->st[4U][1U]), + libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][2U], s->st[1U][2U], + s->st[2U][2U], s->st[3U][2U], + s->st[4U][2U]), + libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][3U], s->st[1U][3U], + s->st[2U][3U], s->st[3U][3U], + s->st[4U][3U]), + libcrux_sha3_portable_keccak_xor5_5a(s->st[0U][4U], s->st[1U][4U], + s->st[2U][4U], s->st[3U][4U], + s->st[4U][4U])}; + uint64_t uu____0 = libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a( + c[((size_t)0U + (size_t)4U) % (size_t)5U], + c[((size_t)0U + (size_t)1U) % (size_t)5U]); + uint64_t uu____1 = libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a( + c[((size_t)1U + (size_t)4U) % (size_t)5U], + c[((size_t)1U + (size_t)1U) % (size_t)5U]); + uint64_t uu____2 = libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a( + c[((size_t)2U + (size_t)4U) % (size_t)5U], + c[((size_t)2U + (size_t)1U) % (size_t)5U]); + uint64_t uu____3 = libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a( + c[((size_t)3U + (size_t)4U) % (size_t)5U], + c[((size_t)3U + (size_t)1U) % (size_t)5U]); + uint64_t t[5U] = {uu____0, uu____1, uu____2, uu____3, + libcrux_sha3_portable_keccak_rotate_left1_and_xor_5a( + c[((size_t)4U + (size_t)4U) % (size_t)5U], + c[((size_t)4U + (size_t)1U) % (size_t)5U])}; + s->st[0U][0U] = libcrux_sha3_portable_keccak_xor_5a(s->st[0U][0U], t[0U]); + s->st[1U][0U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb(s->st[1U][0U], t[0U]); + s->st[2U][0U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb0(s->st[2U][0U], t[0U]); + s->st[3U][0U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb1(s->st[3U][0U], t[0U]); + s->st[4U][0U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb2(s->st[4U][0U], t[0U]); + s->st[0U][1U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb3(s->st[0U][1U], t[1U]); + s->st[1U][1U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb4(s->st[1U][1U], t[1U]); + s->st[2U][1U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb5(s->st[2U][1U], t[1U]); + s->st[3U][1U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb6(s->st[3U][1U], t[1U]); + s->st[4U][1U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb7(s->st[4U][1U], t[1U]); + s->st[0U][2U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb8(s->st[0U][2U], t[2U]); + s->st[1U][2U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb9(s->st[1U][2U], t[2U]); + s->st[2U][2U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb10(s->st[2U][2U], t[2U]); + s->st[3U][2U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb11(s->st[3U][2U], t[2U]); + s->st[4U][2U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb12(s->st[4U][2U], t[2U]); + s->st[0U][3U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb13(s->st[0U][3U], t[3U]); + s->st[1U][3U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb14(s->st[1U][3U], t[3U]); + s->st[2U][3U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb15(s->st[2U][3U], t[3U]); + s->st[3U][3U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb16(s->st[3U][3U], t[3U]); + s->st[4U][3U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb17(s->st[4U][3U], t[3U]); + s->st[0U][4U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb18(s->st[0U][4U], t[4U]); + s->st[1U][4U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb19(s->st[1U][4U], t[4U]); + s->st[2U][4U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb20(s->st[2U][4U], t[4U]); + s->st[3U][4U] = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb21(s->st[3U][4U], t[4U]); + uint64_t uu____27 = + libcrux_sha3_portable_keccak_xor_and_rotate_5a_bb22(s->st[4U][4U], t[4U]); + s->st[4U][4U] = uu____27; +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.pi +with types uint64_t +with const generics +- N= 1 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_pi_1d( + libcrux_sha3_generic_keccak_KeccakState_48 *s) { + uint64_t old[5U][5U]; + memcpy(old, s->st, (size_t)5U * sizeof(uint64_t[5U])); + s->st[0U][1U] = old[1U][1U]; + s->st[0U][2U] = old[2U][2U]; + s->st[0U][3U] = old[3U][3U]; + s->st[0U][4U] = old[4U][4U]; + s->st[1U][0U] = old[0U][3U]; + s->st[1U][1U] = old[1U][4U]; + s->st[1U][2U] = old[2U][0U]; + s->st[1U][3U] = old[3U][1U]; + s->st[1U][4U] = old[4U][2U]; + s->st[2U][0U] = old[0U][1U]; + s->st[2U][1U] = old[1U][2U]; + s->st[2U][2U] = old[2U][3U]; + s->st[2U][3U] = old[3U][4U]; + s->st[2U][4U] = old[4U][0U]; + s->st[3U][0U] = old[0U][4U]; + s->st[3U][1U] = old[1U][0U]; + s->st[3U][2U] = old[2U][1U]; + s->st[3U][3U] = old[3U][2U]; + s->st[3U][4U] = old[4U][3U]; + s->st[4U][0U] = old[0U][2U]; + s->st[4U][1U] = old[1U][3U]; + s->st[4U][2U] = old[2U][4U]; + s->st[4U][3U] = old[3U][0U]; + s->st[4U][4U] = old[4U][1U]; +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.chi +with types uint64_t +with const generics +- N= 1 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_chi_12( + libcrux_sha3_generic_keccak_KeccakState_48 *s) { + uint64_t old[5U][5U]; + memcpy(old, s->st, (size_t)5U * sizeof(uint64_t[5U])); + for (size_t i0 = (size_t)0U; i0 < (size_t)5U; i0++) { + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)5U; i++) { + size_t j = i; + s->st[i1][j] = libcrux_sha3_portable_keccak_and_not_xor_5a( + s->st[i1][j], old[i1][(j + (size_t)2U) % (size_t)5U], + old[i1][(j + (size_t)1U) % (size_t)5U]); + } + } +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.iota +with types uint64_t +with const generics +- N= 1 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_iota_62( + libcrux_sha3_generic_keccak_KeccakState_48 *s, size_t i) { + s->st[0U][0U] = libcrux_sha3_portable_keccak_xor_constant_5a( + s->st[0U][0U], libcrux_sha3_generic_keccak_ROUNDCONSTANTS[i]); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.keccakf1600 +with types uint64_t +with const generics +- N= 1 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccakf1600_21( + libcrux_sha3_generic_keccak_KeccakState_48 *s) { + for (size_t i = (size_t)0U; i < (size_t)24U; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_theta_rho_16(s); + libcrux_sha3_generic_keccak_pi_1d(s); + libcrux_sha3_generic_keccak_chi_12(s); + libcrux_sha3_generic_keccak_iota_62(s, i0); + } +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block +with types uint64_t +with const generics +- N= 1 +- RATE= 72 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block_5a_b8(uu____0, uu____1); + libcrux_sha3_generic_keccak_keccakf1600_21(s); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full +with const generics +- RATE= 72 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)}; + libcrux_sha3_portable_keccak_load_block_2c(s, buf); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a +with const generics +- RATE= 72 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d2( + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_b[1U][200U]; + memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full_df(uu____0, copy_of_b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final +with types uint64_t +with const generics +- N= 1 +- RATE= 72 +- DELIM= 6 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c7( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) { + size_t last_len = Eurydice_slice_len(last[0U], uint8_t); + uint8_t blocks[1U][200U] = {{0U}}; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + if (last_len > (size_t)0U) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice2( + blocks[i0], (size_t)0U, last_len, uint8_t); + Eurydice_slice_copy(uu____0, last[i0], uint8_t); + } + blocks[i0][last_len] = 6U; + size_t uu____1 = i0; + size_t uu____2 = (size_t)72U - (size_t)1U; + blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U; + } + uint64_t(*uu____3)[5U] = s->st; + uint8_t uu____4[1U][200U]; + memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full_5a_d2(uu____3, uu____4); + libcrux_sha3_generic_keccak_keccakf1600_21(s); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block +with const generics +- RATE= 72 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_58( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)72U / (size_t)8U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_slice_subslice2( + out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); + } +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full +with const generics +- RATE= 72 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t)}; + libcrux_sha3_portable_keccak_store_block_58(s, buf); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_out[200U]; + memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a +with const generics +- RATE= 72 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_5a_29( + uint64_t (*a)[5U], uint8_t ret[1U][200U]) { + libcrux_sha3_portable_keccak_store_block_full_2d(a, ret); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last +with types uint64_t +with const generics +- N= 1 +- RATE= 72 +*/ +static KRML_MUSTINLINE void +libcrux_sha3_generic_keccak_squeeze_first_and_last_c5( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full_5a_29(s->st, b); + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range_b3 lit; + lit.start = (size_t)0U; + lit.end = Eurydice_slice_len(out[i0], uint8_t); + Eurydice_slice_copy( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range_b3), + uint8_t); + } +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a +with const generics +- RATE= 72 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_59( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + libcrux_sha3_portable_keccak_store_block_58(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block +with types uint64_t +with const generics +- N= 1 +- RATE= 72 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_84( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak_store_block_5a_59(s->st, out); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block +with types uint64_t +with const generics +- N= 1 +- RATE= 72 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600_21(s); + libcrux_sha3_portable_keccak_store_block_5a_59(s->st, out); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last +with types uint64_t +with const generics +- N= 1 +- RATE= 72 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf( + libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600_21(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full_5a_29(s.st, b); + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range_b3 lit; + lit.start = (size_t)0U; + lit.end = Eurydice_slice_len(out[i0], uint8_t); + Eurydice_slice_copy( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range_b3), + uint8_t); + } +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.keccak +with types uint64_t +with const generics +- N= 1 +- RATE= 72 +- DELIM= 6 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e9( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState_48 s = + libcrux_sha3_generic_keccak_new_1e_f4(); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)72U; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)72U, + (size_t)72U, ret); + libcrux_sha3_generic_keccak_absorb_block_df(uu____0, ret); + } + size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)72U; + libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a( + copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret); + libcrux_sha3_generic_keccak_absorb_final_c7(uu____2, ret); + size_t outlen = Eurydice_slice_len(out[0U], uint8_t); + size_t blocks = outlen / (size_t)72U; + size_t last = outlen - outlen % (size_t)72U; + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last_c5(&s, out); + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____4 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)72U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block_84(&s, o0); + core_ops_range_Range_b3 iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( + (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range_b3, core_ops_range_Range_b3); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, Option_b3) + .tag == None) { + break; + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____5 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(o1, (size_t)72U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block_fc(&s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last_cf(s, o1); + } + } +} + +/** +A monomorphic instance of libcrux_sha3.portable.keccakx1 +with const generics +- RATE= 72 +- DELIM= 6 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak_e9(copy_of_data, out); +} + +/** + A portable SHA3 512 implementation. +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_sha512(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; + libcrux_sha3_portable_keccakx1_ce(buf0, buf); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block +with const generics +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c0( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) { + size_t i0 = i; + uint8_t uu____0[8U]; + Result_56 dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0, + (size_t)8U * i0 + (size_t)8U, uint8_t), + Eurydice_slice, uint8_t[8U]); + unwrap_41_ac(dst, uu____0); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = + s[uu____1][uu____2] ^ core_num__u64_9__from_le_bytes(uu____0); + } +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a +with const generics +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b80( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_b[1U]; + memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block_2c0(uu____0, copy_of_b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block +with types uint64_t +with const generics +- N= 1 +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df0( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block_5a_b80(uu____0, uu____1); + libcrux_sha3_generic_keccak_keccakf1600_21(s); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full +with const generics +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df0( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)}; + libcrux_sha3_portable_keccak_load_block_2c0(s, buf); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a +with const generics +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d20( + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_b[1U][200U]; + memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full_df0(uu____0, copy_of_b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final +with types uint64_t +with const generics +- N= 1 +- RATE= 136 +- DELIM= 6 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c70( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) { + size_t last_len = Eurydice_slice_len(last[0U], uint8_t); + uint8_t blocks[1U][200U] = {{0U}}; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + if (last_len > (size_t)0U) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice2( + blocks[i0], (size_t)0U, last_len, uint8_t); + Eurydice_slice_copy(uu____0, last[i0], uint8_t); + } + blocks[i0][last_len] = 6U; + size_t uu____1 = i0; + size_t uu____2 = (size_t)136U - (size_t)1U; + blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U; + } + uint64_t(*uu____3)[5U] = s->st; + uint8_t uu____4[1U][200U]; + memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full_5a_d20(uu____3, uu____4); + libcrux_sha3_generic_keccak_keccakf1600_21(s); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block +with const generics +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_580( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)136U / (size_t)8U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_slice_subslice2( + out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); + } +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full +with const generics +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d0( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t)}; + libcrux_sha3_portable_keccak_store_block_580(s, buf); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_out[200U]; + memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a +with const generics +- RATE= 136 +*/ +static KRML_MUSTINLINE void +libcrux_sha3_portable_keccak_store_block_full_5a_290(uint64_t (*a)[5U], + uint8_t ret[1U][200U]) { + libcrux_sha3_portable_keccak_store_block_full_2d0(a, ret); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last +with types uint64_t +with const generics +- N= 1 +- RATE= 136 +*/ +static KRML_MUSTINLINE void +libcrux_sha3_generic_keccak_squeeze_first_and_last_c50( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full_5a_290(s->st, b); + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range_b3 lit; + lit.start = (size_t)0U; + lit.end = Eurydice_slice_len(out[i0], uint8_t); + Eurydice_slice_copy( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range_b3), + uint8_t); + } +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a +with const generics +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_590( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + libcrux_sha3_portable_keccak_store_block_580(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block +with types uint64_t +with const generics +- N= 1 +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_840( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak_store_block_5a_590(s->st, out); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block +with types uint64_t +with const generics +- N= 1 +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc0( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600_21(s); + libcrux_sha3_portable_keccak_store_block_5a_590(s->st, out); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last +with types uint64_t +with const generics +- N= 1 +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf0( + libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600_21(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full_5a_290(s.st, b); + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range_b3 lit; + lit.start = (size_t)0U; + lit.end = Eurydice_slice_len(out[i0], uint8_t); + Eurydice_slice_copy( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range_b3), + uint8_t); + } +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.keccak +with types uint64_t +with const generics +- N= 1 +- RATE= 136 +- DELIM= 6 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e90( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState_48 s = + libcrux_sha3_generic_keccak_new_1e_f4(); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)136U; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)136U, + (size_t)136U, ret); + libcrux_sha3_generic_keccak_absorb_block_df0(uu____0, ret); + } + size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)136U; + libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a( + copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret); + libcrux_sha3_generic_keccak_absorb_final_c70(uu____2, ret); + size_t outlen = Eurydice_slice_len(out[0U], uint8_t); + size_t blocks = outlen / (size_t)136U; + size_t last = outlen - outlen % (size_t)136U; + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last_c50(&s, out); + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____4 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)136U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block_840(&s, o0); + core_ops_range_Range_b3 iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( + (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range_b3, core_ops_range_Range_b3); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, Option_b3) + .tag == None) { + break; + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____5 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(o1, (size_t)136U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block_fc0(&s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last_cf0(s, o1); + } + } +} + +/** +A monomorphic instance of libcrux_sha3.portable.keccakx1 +with const generics +- RATE= 136 +- DELIM= 6 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce0( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak_e90(copy_of_data, out); +} + +/** + A portable SHA3 256 implementation. +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_sha256(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; + libcrux_sha3_portable_keccakx1_ce0(buf0, buf); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final +with types uint64_t +with const generics +- N= 1 +- RATE= 136 +- DELIM= 31 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c71( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) { + size_t last_len = Eurydice_slice_len(last[0U], uint8_t); + uint8_t blocks[1U][200U] = {{0U}}; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + if (last_len > (size_t)0U) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice2( + blocks[i0], (size_t)0U, last_len, uint8_t); + Eurydice_slice_copy(uu____0, last[i0], uint8_t); + } + blocks[i0][last_len] = 31U; + size_t uu____1 = i0; + size_t uu____2 = (size_t)136U - (size_t)1U; + blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U; + } + uint64_t(*uu____3)[5U] = s->st; + uint8_t uu____4[1U][200U]; + memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full_5a_d20(uu____3, uu____4); + libcrux_sha3_generic_keccak_keccakf1600_21(s); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.keccak +with types uint64_t +with const generics +- N= 1 +- RATE= 136 +- DELIM= 31 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e91( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState_48 s = + libcrux_sha3_generic_keccak_new_1e_f4(); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)136U; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)136U, + (size_t)136U, ret); + libcrux_sha3_generic_keccak_absorb_block_df0(uu____0, ret); + } + size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)136U; + libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a( + copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret); + libcrux_sha3_generic_keccak_absorb_final_c71(uu____2, ret); + size_t outlen = Eurydice_slice_len(out[0U], uint8_t); + size_t blocks = outlen / (size_t)136U; + size_t last = outlen - outlen % (size_t)136U; + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last_c50(&s, out); + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____4 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)136U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block_840(&s, o0); + core_ops_range_Range_b3 iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( + (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range_b3, core_ops_range_Range_b3); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, Option_b3) + .tag == None) { + break; + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____5 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(o1, (size_t)136U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block_fc0(&s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last_cf0(s, o1); + } + } +} + +/** +A monomorphic instance of libcrux_sha3.portable.keccakx1 +with const generics +- RATE= 136 +- DELIM= 31 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce1( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak_e91(copy_of_data, out); +} + +/** + A portable SHAKE256 implementation. +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_shake256( + Eurydice_slice digest, Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; + libcrux_sha3_portable_keccakx1_ce1(buf0, buf); +} + +typedef libcrux_sha3_generic_keccak_KeccakState_48 + libcrux_sha3_portable_KeccakState; + +/** + Create a new SHAKE-128 state object. +*/ +static KRML_MUSTINLINE libcrux_sha3_generic_keccak_KeccakState_48 +libcrux_sha3_portable_incremental_shake128_init(void) { + return libcrux_sha3_generic_keccak_new_1e_f4(); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block +with const generics +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c1( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) { + size_t i0 = i; + uint8_t uu____0[8U]; + Result_56 dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0, + (size_t)8U * i0 + (size_t)8U, uint8_t), + Eurydice_slice, uint8_t[8U]); + unwrap_41_ac(dst, uu____0); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = + s[uu____1][uu____2] ^ core_num__u64_9__from_le_bytes(uu____0); + } +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full +with const generics +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df1( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)}; + libcrux_sha3_portable_keccak_load_block_2c1(s, buf); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a +with const generics +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d21( + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_b[1U][200U]; + memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full_df1(uu____0, copy_of_b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final +with types uint64_t +with const generics +- N= 1 +- RATE= 168 +- DELIM= 31 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c72( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) { + size_t last_len = Eurydice_slice_len(last[0U], uint8_t); + uint8_t blocks[1U][200U] = {{0U}}; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + if (last_len > (size_t)0U) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice2( + blocks[i0], (size_t)0U, last_len, uint8_t); + Eurydice_slice_copy(uu____0, last[i0], uint8_t); + } + blocks[i0][last_len] = 31U; + size_t uu____1 = i0; + size_t uu____2 = (size_t)168U - (size_t)1U; + blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U; + } + uint64_t(*uu____3)[5U] = s->st; + uint8_t uu____4[1U][200U]; + memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full_5a_d21(uu____3, uu____4); + libcrux_sha3_generic_keccak_keccakf1600_21(s); +} + +/** + Absorb +*/ +static KRML_MUSTINLINE void +libcrux_sha3_portable_incremental_shake128_absorb_final( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice data0) { + Eurydice_slice buf[1U] = {data0}; + libcrux_sha3_generic_keccak_absorb_final_c72(s, buf); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block +with const generics +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_581( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)8U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_slice_subslice2( + out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); + } +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a +with const generics +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_591( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + libcrux_sha3_portable_keccak_store_block_581(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block +with types uint64_t +with const generics +- N= 1 +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc1( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600_21(s); + libcrux_sha3_portable_keccak_store_block_5a_591(s->st, out); +} + +/** + Squeeze another block +*/ +static KRML_MUSTINLINE void +libcrux_sha3_portable_incremental_shake128_squeeze_next_block( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out0) { + Eurydice_slice buf[1U] = {out0}; + libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, buf); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block +with types uint64_t +with const generics +- N= 1 +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_841( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak_store_block_5a_591(s->st, out); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_three_blocks +with types uint64_t +with const generics +- N= 1 +- RATE= 168 +*/ +static KRML_MUSTINLINE void +libcrux_sha3_generic_keccak_squeeze_first_three_blocks_cc( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + Eurydice_slice_uint8_t_1size_t__x2 uu____0 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)168U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o10[1U]; + memcpy(o10, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block_841(s, o0); + Eurydice_slice_uint8_t_1size_t__x2 uu____1 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(o10, (size_t)168U); + Eurydice_slice o1[1U]; + memcpy(o1, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o2[1U]; + memcpy(o2, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o1); + libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o2); +} + +/** + Squeeze three blocks +*/ +static KRML_MUSTINLINE void +libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out0) { + Eurydice_slice buf[1U] = {out0}; + libcrux_sha3_generic_keccak_squeeze_first_three_blocks_cc(s, buf); +} + +#define libcrux_sha3_Sha224 0 +#define libcrux_sha3_Sha256 1 +#define libcrux_sha3_Sha384 2 +#define libcrux_sha3_Sha512 3 + +typedef uint8_t libcrux_sha3_Algorithm; + +/** + Returns the output size of a digest. +*/ +static inline size_t libcrux_sha3_digest_size(libcrux_sha3_Algorithm mode) { + size_t uu____0; + switch (mode) { + case libcrux_sha3_Sha224: { + uu____0 = (size_t)28U; + break; + } + case libcrux_sha3_Sha256: { + uu____0 = (size_t)32U; + break; + } + case libcrux_sha3_Sha384: { + uu____0 = (size_t)48U; + break; + } + case libcrux_sha3_Sha512: { + uu____0 = (size_t)64U; + break; + } + default: { + KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, + __LINE__); + KRML_HOST_EXIT(253U); + } + } + return uu____0; +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block +with const generics +- RATE= 144 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c2( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) { + size_t i0 = i; + uint8_t uu____0[8U]; + Result_56 dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0, + (size_t)8U * i0 + (size_t)8U, uint8_t), + Eurydice_slice, uint8_t[8U]); + unwrap_41_ac(dst, uu____0); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = + s[uu____1][uu____2] ^ core_num__u64_9__from_le_bytes(uu____0); + } +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a +with const generics +- RATE= 144 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b81( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_b[1U]; + memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block_2c2(uu____0, copy_of_b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block +with types uint64_t +with const generics +- N= 1 +- RATE= 144 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df1( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block_5a_b81(uu____0, uu____1); + libcrux_sha3_generic_keccak_keccakf1600_21(s); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full +with const generics +- RATE= 144 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df2( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)}; + libcrux_sha3_portable_keccak_load_block_2c2(s, buf); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a +with const generics +- RATE= 144 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d22( + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_b[1U][200U]; + memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full_df2(uu____0, copy_of_b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final +with types uint64_t +with const generics +- N= 1 +- RATE= 144 +- DELIM= 6 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c73( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) { + size_t last_len = Eurydice_slice_len(last[0U], uint8_t); + uint8_t blocks[1U][200U] = {{0U}}; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + if (last_len > (size_t)0U) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice2( + blocks[i0], (size_t)0U, last_len, uint8_t); + Eurydice_slice_copy(uu____0, last[i0], uint8_t); + } + blocks[i0][last_len] = 6U; + size_t uu____1 = i0; + size_t uu____2 = (size_t)144U - (size_t)1U; + blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U; + } + uint64_t(*uu____3)[5U] = s->st; + uint8_t uu____4[1U][200U]; + memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full_5a_d22(uu____3, uu____4); + libcrux_sha3_generic_keccak_keccakf1600_21(s); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block +with const generics +- RATE= 144 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_582( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)144U / (size_t)8U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_slice_subslice2( + out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); + } +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full +with const generics +- RATE= 144 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d1( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t)}; + libcrux_sha3_portable_keccak_store_block_582(s, buf); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_out[200U]; + memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a +with const generics +- RATE= 144 +*/ +static KRML_MUSTINLINE void +libcrux_sha3_portable_keccak_store_block_full_5a_291(uint64_t (*a)[5U], + uint8_t ret[1U][200U]) { + libcrux_sha3_portable_keccak_store_block_full_2d1(a, ret); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last +with types uint64_t +with const generics +- N= 1 +- RATE= 144 +*/ +static KRML_MUSTINLINE void +libcrux_sha3_generic_keccak_squeeze_first_and_last_c51( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full_5a_291(s->st, b); + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range_b3 lit; + lit.start = (size_t)0U; + lit.end = Eurydice_slice_len(out[i0], uint8_t); + Eurydice_slice_copy( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range_b3), + uint8_t); + } +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a +with const generics +- RATE= 144 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_592( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + libcrux_sha3_portable_keccak_store_block_582(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block +with types uint64_t +with const generics +- N= 1 +- RATE= 144 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_842( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak_store_block_5a_592(s->st, out); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block +with types uint64_t +with const generics +- N= 1 +- RATE= 144 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc2( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600_21(s); + libcrux_sha3_portable_keccak_store_block_5a_592(s->st, out); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last +with types uint64_t +with const generics +- N= 1 +- RATE= 144 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf1( + libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600_21(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full_5a_291(s.st, b); + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range_b3 lit; + lit.start = (size_t)0U; + lit.end = Eurydice_slice_len(out[i0], uint8_t); + Eurydice_slice_copy( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range_b3), + uint8_t); + } +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.keccak +with types uint64_t +with const generics +- N= 1 +- RATE= 144 +- DELIM= 6 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e92( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState_48 s = + libcrux_sha3_generic_keccak_new_1e_f4(); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)144U; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)144U, + (size_t)144U, ret); + libcrux_sha3_generic_keccak_absorb_block_df1(uu____0, ret); + } + size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)144U; + libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a( + copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret); + libcrux_sha3_generic_keccak_absorb_final_c73(uu____2, ret); + size_t outlen = Eurydice_slice_len(out[0U], uint8_t); + size_t blocks = outlen / (size_t)144U; + size_t last = outlen - outlen % (size_t)144U; + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last_c51(&s, out); + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____4 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)144U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block_842(&s, o0); + core_ops_range_Range_b3 iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( + (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range_b3, core_ops_range_Range_b3); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, Option_b3) + .tag == None) { + break; + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____5 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(o1, (size_t)144U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block_fc2(&s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last_cf1(s, o1); + } + } +} + +/** +A monomorphic instance of libcrux_sha3.portable.keccakx1 +with const generics +- RATE= 144 +- DELIM= 6 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce2( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak_e92(copy_of_data, out); +} + +/** + A portable SHA3 224 implementation. +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_sha224(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; + libcrux_sha3_portable_keccakx1_ce2(buf0, buf); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block +with const generics +- RATE= 104 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_2c3( + uint64_t (*s)[5U], Eurydice_slice blocks[1U]) { + for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) { + size_t i0 = i; + uint8_t uu____0[8U]; + Result_56 dst; + Eurydice_slice_to_array2( + &dst, + Eurydice_slice_subslice2(blocks[0U], (size_t)8U * i0, + (size_t)8U * i0 + (size_t)8U, uint8_t), + Eurydice_slice, uint8_t[8U]); + unwrap_41_ac(dst, uu____0); + size_t uu____1 = i0 / (size_t)5U; + size_t uu____2 = i0 % (size_t)5U; + s[uu____1][uu____2] = + s[uu____1][uu____2] ^ core_num__u64_9__from_le_bytes(uu____0); + } +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a +with const generics +- RATE= 104 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b82( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_b[1U]; + memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block_2c3(uu____0, copy_of_b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block +with types uint64_t +with const generics +- N= 1 +- RATE= 104 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df2( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block_5a_b82(uu____0, uu____1); + libcrux_sha3_generic_keccak_keccakf1600_21(s); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full +with const generics +- RATE= 104 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_df3( + uint64_t (*s)[5U], uint8_t blocks[1U][200U]) { + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, blocks[0U], uint8_t)}; + libcrux_sha3_portable_keccak_load_block_2c3(s, buf); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_full_5a +with const generics +- RATE= 104 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_full_5a_d23( + uint64_t (*a)[5U], uint8_t b[1U][200U]) { + uint64_t(*uu____0)[5U] = a; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_b[1U][200U]; + memcpy(copy_of_b, b, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full_df3(uu____0, copy_of_b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final +with types uint64_t +with const generics +- N= 1 +- RATE= 104 +- DELIM= 6 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_c74( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice last[1U]) { + size_t last_len = Eurydice_slice_len(last[0U], uint8_t); + uint8_t blocks[1U][200U] = {{0U}}; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + if (last_len > (size_t)0U) { + Eurydice_slice uu____0 = Eurydice_array_to_subslice2( + blocks[i0], (size_t)0U, last_len, uint8_t); + Eurydice_slice_copy(uu____0, last[i0], uint8_t); + } + blocks[i0][last_len] = 6U; + size_t uu____1 = i0; + size_t uu____2 = (size_t)104U - (size_t)1U; + blocks[uu____1][uu____2] = (uint32_t)blocks[uu____1][uu____2] | 128U; + } + uint64_t(*uu____3)[5U] = s->st; + uint8_t uu____4[1U][200U]; + memcpy(uu____4, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full_5a_d23(uu____3, uu____4); + libcrux_sha3_generic_keccak_keccakf1600_21(s); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block +with const generics +- RATE= 104 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_583( + uint64_t (*s)[5U], Eurydice_slice out[1U]) { + for (size_t i = (size_t)0U; i < (size_t)104U / (size_t)8U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_slice_subslice2( + out[0U], (size_t)8U * i0, (size_t)8U * i0 + (size_t)8U, uint8_t); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(s[i0 / (size_t)5U][i0 % (size_t)5U], ret); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); + } +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full +with const generics +- RATE= 104 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d2( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t)}; + libcrux_sha3_portable_keccak_store_block_583(s, buf); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_out[200U]; + memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a +with const generics +- RATE= 104 +*/ +static KRML_MUSTINLINE void +libcrux_sha3_portable_keccak_store_block_full_5a_292(uint64_t (*a)[5U], + uint8_t ret[1U][200U]) { + libcrux_sha3_portable_keccak_store_block_full_2d2(a, ret); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last +with types uint64_t +with const generics +- N= 1 +- RATE= 104 +*/ +static KRML_MUSTINLINE void +libcrux_sha3_generic_keccak_squeeze_first_and_last_c52( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full_5a_292(s->st, b); + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range_b3 lit; + lit.start = (size_t)0U; + lit.end = Eurydice_slice_len(out[i0], uint8_t); + Eurydice_slice_copy( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range_b3), + uint8_t); + } +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_5a +with const generics +- RATE= 104 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_5a_593( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + libcrux_sha3_portable_keccak_store_block_583(a, b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_block +with types uint64_t +with const generics +- N= 1 +- RATE= 104 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_first_block_843( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + libcrux_sha3_portable_keccak_store_block_5a_593(s->st, out); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_next_block +with types uint64_t +with const generics +- N= 1 +- RATE= 104 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_next_block_fc3( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600_21(s); + libcrux_sha3_portable_keccak_store_block_5a_593(s->st, out); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last +with types uint64_t +with const generics +- N= 1 +- RATE= 104 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf2( + libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600_21(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full_5a_292(s.st, b); + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range_b3 lit; + lit.start = (size_t)0U; + lit.end = Eurydice_slice_len(out[i0], uint8_t); + Eurydice_slice_copy( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range_b3), + uint8_t); + } +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.keccak +with types uint64_t +with const generics +- N= 1 +- RATE= 104 +- DELIM= 6 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e93( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState_48 s = + libcrux_sha3_generic_keccak_new_1e_f4(); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)104U; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)104U, + (size_t)104U, ret); + libcrux_sha3_generic_keccak_absorb_block_df2(uu____0, ret); + } + size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)104U; + libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a( + copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret); + libcrux_sha3_generic_keccak_absorb_final_c74(uu____2, ret); + size_t outlen = Eurydice_slice_len(out[0U], uint8_t); + size_t blocks = outlen / (size_t)104U; + size_t last = outlen - outlen % (size_t)104U; + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last_c52(&s, out); + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____4 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)104U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block_843(&s, o0); + core_ops_range_Range_b3 iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( + (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range_b3, core_ops_range_Range_b3); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, Option_b3) + .tag == None) { + break; + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____5 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(o1, (size_t)104U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block_fc3(&s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last_cf2(s, o1); + } + } +} + +/** +A monomorphic instance of libcrux_sha3.portable.keccakx1 +with const generics +- RATE= 104 +- DELIM= 6 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce3( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak_e93(copy_of_data, out); +} + +/** + A portable SHA3 384 implementation. +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_sha384(Eurydice_slice digest, + Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; + libcrux_sha3_portable_keccakx1_ce3(buf0, buf); +} + +/** + SHA3 224 + + Preconditions: + - `digest.len() == 28` +*/ +static KRML_MUSTINLINE void libcrux_sha3_sha224_ema(Eurydice_slice digest, + Eurydice_slice payload) { + libcrux_sha3_portable_sha224(digest, payload); +} + +/** + SHA3 224 +*/ +static KRML_MUSTINLINE void libcrux_sha3_sha224(Eurydice_slice data, + uint8_t ret[28U]) { + uint8_t out[28U] = {0U}; + libcrux_sha3_sha224_ema(Eurydice_array_to_slice((size_t)28U, out, uint8_t), + data); + memcpy(ret, out, (size_t)28U * sizeof(uint8_t)); +} + +/** + SHA3 256 +*/ +static KRML_MUSTINLINE void libcrux_sha3_sha256_ema(Eurydice_slice digest, + Eurydice_slice payload) { + libcrux_sha3_portable_sha256(digest, payload); +} + +/** + SHA3 256 +*/ +static KRML_MUSTINLINE void libcrux_sha3_sha256(Eurydice_slice data, + uint8_t ret[32U]) { + uint8_t out[32U] = {0U}; + libcrux_sha3_sha256_ema(Eurydice_array_to_slice((size_t)32U, out, uint8_t), + data); + memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); +} + +/** + SHA3 384 +*/ +static KRML_MUSTINLINE void libcrux_sha3_sha384_ema(Eurydice_slice digest, + Eurydice_slice payload) { + libcrux_sha3_portable_sha384(digest, payload); +} + +/** + SHA3 384 +*/ +static KRML_MUSTINLINE void libcrux_sha3_sha384(Eurydice_slice data, + uint8_t ret[48U]) { + uint8_t out[48U] = {0U}; + libcrux_sha3_sha384_ema(Eurydice_array_to_slice((size_t)48U, out, uint8_t), + data); + memcpy(ret, out, (size_t)48U * sizeof(uint8_t)); +} + +/** + SHA3 512 +*/ +static KRML_MUSTINLINE void libcrux_sha3_sha512_ema(Eurydice_slice digest, + Eurydice_slice payload) { + libcrux_sha3_portable_sha512(digest, payload); +} + +/** + SHA3 512 +*/ +static KRML_MUSTINLINE void libcrux_sha3_sha512(Eurydice_slice data, + uint8_t ret[64U]) { + uint8_t out[64U] = {0U}; + libcrux_sha3_sha512_ema(Eurydice_array_to_slice((size_t)64U, out, uint8_t), + data); + memcpy(ret, out, (size_t)64U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.load_block_5a +with const generics +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_load_block_5a_b83( + uint64_t (*a)[5U], Eurydice_slice b[1U]) { + uint64_t(*uu____0)[5U] = a; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_b[1U]; + memcpy(copy_of_b, b, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block_2c1(uu____0, copy_of_b); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_block +with types uint64_t +with const generics +- N= 1 +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_block_df3( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice blocks[1U]) { + uint64_t(*uu____0)[5U] = s->st; + Eurydice_slice uu____1[1U]; + memcpy(uu____1, blocks, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block_5a_b83(uu____0, uu____1); + libcrux_sha3_generic_keccak_keccakf1600_21(s); +} + +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full +with const generics +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_block_full_2d3( + uint64_t (*s)[5U], uint8_t ret[1U][200U]) { + uint8_t out[200U] = {0U}; + Eurydice_slice buf[1U] = { + Eurydice_array_to_slice((size_t)200U, out, uint8_t)}; + libcrux_sha3_portable_keccak_store_block_581(s, buf); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_out[200U]; + memcpy(copy_of_out, out, (size_t)200U * sizeof(uint8_t)); + memcpy(ret[0U], copy_of_out, (size_t)200U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_block_full_5a +with const generics +- RATE= 168 +*/ +static KRML_MUSTINLINE void +libcrux_sha3_portable_keccak_store_block_full_5a_293(uint64_t (*a)[5U], + uint8_t ret[1U][200U]) { + libcrux_sha3_portable_keccak_store_block_full_2d3(a, ret); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_and_last +with types uint64_t +with const generics +- N= 1 +- RATE= 168 +*/ +static KRML_MUSTINLINE void +libcrux_sha3_generic_keccak_squeeze_first_and_last_c53( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full_5a_293(s->st, b); + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range_b3 lit; + lit.start = (size_t)0U; + lit.end = Eurydice_slice_len(out[i0], uint8_t); + Eurydice_slice_copy( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range_b3), + uint8_t); + } +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_last +with types uint64_t +with const generics +- N= 1 +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_last_cf3( + libcrux_sha3_generic_keccak_KeccakState_48 s, Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_keccakf1600_21(&s); + uint8_t b[1U][200U]; + libcrux_sha3_portable_keccak_store_block_full_5a_293(s.st, b); + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = out[i0]; + uint8_t *uu____1 = b[i0]; + core_ops_range_Range_b3 lit; + lit.start = (size_t)0U; + lit.end = Eurydice_slice_len(out[i0], uint8_t); + Eurydice_slice_copy( + uu____0, + Eurydice_array_to_subslice((size_t)200U, uu____1, lit, uint8_t, + core_ops_range_Range_b3), + uint8_t); + } +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.keccak +with types uint64_t +with const generics +- N= 1 +- RATE= 168 +- DELIM= 31 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_keccak_e94( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + libcrux_sha3_generic_keccak_KeccakState_48 s = + libcrux_sha3_generic_keccak_new_1e_f4(); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(data[0U], uint8_t) / (size_t)168U; i++) { + size_t i0 = i; + libcrux_sha3_generic_keccak_KeccakState_48 *uu____0 = &s; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a(copy_of_data, i0 * (size_t)168U, + (size_t)168U, ret); + libcrux_sha3_generic_keccak_absorb_block_df3(uu____0, ret); + } + size_t rem = Eurydice_slice_len(data[0U], uint8_t) % (size_t)168U; + libcrux_sha3_generic_keccak_KeccakState_48 *uu____2 = &s; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a( + copy_of_data, Eurydice_slice_len(data[0U], uint8_t) - rem, rem, ret); + libcrux_sha3_generic_keccak_absorb_final_c72(uu____2, ret); + size_t outlen = Eurydice_slice_len(out[0U], uint8_t); + size_t blocks = outlen / (size_t)168U; + size_t last = outlen - outlen % (size_t)168U; + if (blocks == (size_t)0U) { + libcrux_sha3_generic_keccak_squeeze_first_and_last_c53(&s, out); + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____4 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)168U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____4.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o1[1U]; + memcpy(o1, uu____4.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block_841(&s, o0); + core_ops_range_Range_b3 iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( + (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range_b3, core_ops_range_Range_b3); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, Option_b3) + .tag == None) { + break; + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____5 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(o1, (size_t)168U); + Eurydice_slice o[1U]; + memcpy(o, uu____5.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice orest[1U]; + memcpy(orest, uu____5.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block_fc1(&s, o); + memcpy(o1, orest, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < outlen) { + libcrux_sha3_generic_keccak_squeeze_last_cf3(s, o1); + } + } +} + +/** +A monomorphic instance of libcrux_sha3.portable.keccakx1 +with const generics +- RATE= 168 +- DELIM= 31 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccakx1_ce4( + Eurydice_slice data[1U], Eurydice_slice out[1U]) { + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_data[1U]; + memcpy(copy_of_data, data, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccak_e94(copy_of_data, out); +} + +/** + A portable SHAKE128 implementation. +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_shake128( + Eurydice_slice digest, Eurydice_slice data) { + Eurydice_slice buf0[1U] = {data}; + Eurydice_slice buf[1U] = {digest}; + libcrux_sha3_portable_keccakx1_ce4(buf0, buf); +} + +/** + SHAKE 128 + + Writes `out.len()` bytes. +*/ +static KRML_MUSTINLINE void libcrux_sha3_shake128_ema(Eurydice_slice out, + Eurydice_slice data) { + libcrux_sha3_portable_shake128(out, data); +} + +/** + SHAKE 256 + + Writes `out.len()` bytes. +*/ +static KRML_MUSTINLINE void libcrux_sha3_shake256_ema(Eurydice_slice out, + Eurydice_slice data) { + libcrux_sha3_portable_shake256(out, data); +} + +static const size_t libcrux_sha3_generic_keccak__PI[24U] = { + (size_t)6U, (size_t)12U, (size_t)18U, (size_t)24U, (size_t)3U, + (size_t)9U, (size_t)10U, (size_t)16U, (size_t)22U, (size_t)1U, + (size_t)7U, (size_t)13U, (size_t)19U, (size_t)20U, (size_t)4U, + (size_t)5U, (size_t)11U, (size_t)17U, (size_t)23U, (size_t)2U, + (size_t)8U, (size_t)14U, (size_t)15U, (size_t)21U}; + +static const size_t libcrux_sha3_generic_keccak__ROTC[24U] = { + (size_t)1U, (size_t)62U, (size_t)28U, (size_t)27U, (size_t)36U, + (size_t)44U, (size_t)6U, (size_t)55U, (size_t)20U, (size_t)3U, + (size_t)10U, (size_t)43U, (size_t)25U, (size_t)39U, (size_t)41U, + (size_t)45U, (size_t)15U, (size_t)21U, (size_t)8U, (size_t)18U, + (size_t)2U, (size_t)61U, (size_t)56U, (size_t)14U}; + +/** + A portable SHA3 224 implementation. +*/ +static KRML_MUSTINLINE void libcrux_sha3_neon_sha224(Eurydice_slice digest, + Eurydice_slice data) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +/** + A portable SHA3 256 implementation. +*/ +static KRML_MUSTINLINE void libcrux_sha3_neon_sha256(Eurydice_slice digest, + Eurydice_slice data) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +/** + A portable SHA3 384 implementation. +*/ +static KRML_MUSTINLINE void libcrux_sha3_neon_sha384(Eurydice_slice digest, + Eurydice_slice data) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +/** + A portable SHA3 512 implementation. +*/ +static KRML_MUSTINLINE void libcrux_sha3_neon_sha512(Eurydice_slice digest, + Eurydice_slice data) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +/** + Run SHAKE256 on both inputs in parallel. + + Writes the two results into `out0` and `out1` +*/ +static KRML_MUSTINLINE void libcrux_sha3_neon_x2_shake256(Eurydice_slice input0, + Eurydice_slice input1, + Eurydice_slice out0, + Eurydice_slice out1) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +typedef struct libcrux_sha3_neon_x2_incremental_KeccakState_s { + libcrux_sha3_generic_keccak_KeccakState_48 state[2U]; +} libcrux_sha3_neon_x2_incremental_KeccakState; + +/** + Initialise the `KeccakState2`. +*/ +static KRML_MUSTINLINE libcrux_sha3_neon_x2_incremental_KeccakState +libcrux_sha3_neon_x2_incremental_shake128_init(void) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +/** + Shake128 absorb `data0` and `data1` in the [`KeccakState`] `s`. +*/ +static KRML_MUSTINLINE void +libcrux_sha3_neon_x2_incremental_shake128_absorb_final( + libcrux_sha3_neon_x2_incremental_KeccakState *s, Eurydice_slice data0, + Eurydice_slice data1) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +/** + Squeeze 2 times the first three blocks in parallel in the + [`KeccakState`] and return the output in `out0` and `out1`. +*/ +static KRML_MUSTINLINE void +libcrux_sha3_neon_x2_incremental_shake128_squeeze_first_three_blocks( + libcrux_sha3_neon_x2_incremental_KeccakState *s, Eurydice_slice out0, + Eurydice_slice out1) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +/** + Squeeze 2 times the next block in parallel in the + [`KeccakState`] and return the output in `out0` and `out1`. +*/ +static KRML_MUSTINLINE void +libcrux_sha3_neon_x2_incremental_shake128_squeeze_next_block( + libcrux_sha3_neon_x2_incremental_KeccakState *s, Eurydice_slice out0, + Eurydice_slice out1) { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_first_five_blocks +with types uint64_t +with const generics +- N= 1 +- RATE= 168 +*/ +static KRML_MUSTINLINE void +libcrux_sha3_generic_keccak_squeeze_first_five_blocks_4f( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out[1U]) { + Eurydice_slice_uint8_t_1size_t__x2 uu____0 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, (size_t)168U); + Eurydice_slice o0[1U]; + memcpy(o0, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o10[1U]; + memcpy(o10, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_first_block_841(s, o0); + Eurydice_slice_uint8_t_1size_t__x2 uu____1 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(o10, (size_t)168U); + Eurydice_slice o1[1U]; + memcpy(o1, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o20[1U]; + memcpy(o20, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o1); + Eurydice_slice_uint8_t_1size_t__x2 uu____2 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(o20, (size_t)168U); + Eurydice_slice o2[1U]; + memcpy(o2, uu____2.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o30[1U]; + memcpy(o30, uu____2.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o2); + Eurydice_slice_uint8_t_1size_t__x2 uu____3 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(o30, (size_t)168U); + Eurydice_slice o3[1U]; + memcpy(o3, uu____3.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice o4[1U]; + memcpy(o4, uu____3.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o3); + libcrux_sha3_generic_keccak_squeeze_next_block_fc1(s, o4); +} + +/** + Squeeze five blocks +*/ +static KRML_MUSTINLINE void +libcrux_sha3_portable_incremental_shake128_squeeze_first_five_blocks( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out0) { + Eurydice_slice buf[1U] = {out0}; + libcrux_sha3_generic_keccak_squeeze_first_five_blocks_4f(s, buf); +} + +/** + Absorb some data for SHAKE-256 for the last time +*/ +static KRML_MUSTINLINE void +libcrux_sha3_portable_incremental_shake256_absorb_final( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice data) { + Eurydice_slice buf[1U] = {data}; + libcrux_sha3_generic_keccak_absorb_final_c71(s, buf); +} + +/** + Create a new SHAKE-256 state object. +*/ +static KRML_MUSTINLINE libcrux_sha3_generic_keccak_KeccakState_48 +libcrux_sha3_portable_incremental_shake256_init(void) { + return libcrux_sha3_generic_keccak_new_1e_f4(); +} + +/** + Squeeze the first SHAKE-256 block +*/ +static KRML_MUSTINLINE void +libcrux_sha3_portable_incremental_shake256_squeeze_first_block( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out) { + Eurydice_slice buf[1U] = {out}; + libcrux_sha3_generic_keccak_squeeze_first_block_840(s, buf); +} + +/** + Squeeze the next SHAKE-256 block +*/ +static KRML_MUSTINLINE void +libcrux_sha3_portable_incremental_shake256_squeeze_next_block( + libcrux_sha3_generic_keccak_KeccakState_48 *s, Eurydice_slice out) { + Eurydice_slice buf[1U] = {out}; + libcrux_sha3_generic_keccak_squeeze_next_block_fc0(s, buf); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.KeccakXofState +with types uint64_t +with const generics +- $1size_t +- $136size_t +*/ +typedef struct libcrux_sha3_generic_keccak_KeccakXofState_4f_s { + libcrux_sha3_generic_keccak_KeccakState_48 inner; + uint8_t buf[1U][136U]; + size_t buf_len; + bool sponge; +} libcrux_sha3_generic_keccak_KeccakXofState_4f; + +typedef libcrux_sha3_generic_keccak_KeccakXofState_4f + libcrux_sha3_portable_incremental_Shake256Absorb; + +/** + Consume the internal buffer and the required amount of the input to pad to + `RATE`. + + Returns the `consumed` bytes from `inputs` if there's enough buffered + content to consume, and `0` otherwise. + If `consumed > 0` is returned, `self.buf` contains a full block to be + loaded. +*/ +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.fill_buffer_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 136 +*/ +static inline size_t libcrux_sha3_generic_keccak_fill_buffer_9d_b0( + libcrux_sha3_generic_keccak_KeccakXofState_4f *self, + Eurydice_slice inputs[1U]) { + size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t); + size_t consumed = (size_t)0U; + if (self->buf_len > (size_t)0U) { + if (self->buf_len + input_len >= (size_t)136U) { + consumed = (size_t)136U - self->buf_len; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)136U, self->buf[i0], self->buf_len, uint8_t, size_t); + Eurydice_slice_copy( + uu____0, + Eurydice_slice_subslice_to(inputs[i0], consumed, uint8_t, size_t), + uint8_t); + } + self->buf_len = self->buf_len + consumed; + } + } + return consumed; +} + +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_full_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 136 +*/ +static inline size_t libcrux_sha3_generic_keccak_absorb_full_9d_f8( + libcrux_sha3_generic_keccak_KeccakXofState_4f *self, + Eurydice_slice inputs[1U]) { + libcrux_sha3_generic_keccak_KeccakXofState_4f *uu____0 = self; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_inputs0[1U]; + memcpy(copy_of_inputs0, inputs, (size_t)1U * sizeof(Eurydice_slice)); + size_t input_consumed = + libcrux_sha3_generic_keccak_fill_buffer_9d_b0(uu____0, copy_of_inputs0); + if (input_consumed > (size_t)0U) { + Eurydice_slice borrowed[1U]; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + uint8_t buf[136U] = {0U}; + borrowed[i] = core_array___Array_T__N__23__as_slice( + (size_t)136U, buf, uint8_t, Eurydice_slice); + } + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + borrowed[i0] = + Eurydice_array_to_slice((size_t)136U, self->buf[i0], uint8_t); + } + uint64_t(*uu____2)[5U] = self->inner.st; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, borrowed, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block_5a_b80(uu____2, uu____3); + libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + self->buf_len = (size_t)0U; + } + size_t input_to_consume = + Eurydice_slice_len(inputs[0U], uint8_t) - input_consumed; + size_t num_blocks = input_to_consume / (size_t)136U; + size_t remainder = input_to_consume % (size_t)136U; + for (size_t i = (size_t)0U; i < num_blocks; i++) { + size_t i0 = i; + uint64_t(*uu____4)[5U] = self->inner.st; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_inputs[1U]; + memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a( + copy_of_inputs, input_consumed + i0 * (size_t)136U, (size_t)136U, ret); + libcrux_sha3_portable_keccak_load_block_5a_b80(uu____4, ret); + libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + } + return remainder; +} + +/** + Absorb + + This function takes any number of bytes to absorb and buffers if it's not + enough. The function assumes that all input slices in `blocks` have the same + length. + + Only a multiple of `RATE` blocks are absorbed. + For the remaining bytes [`absorb_final`] needs to be called. + + This works best with relatively small `inputs`. +*/ +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_9d_7b( + libcrux_sha3_generic_keccak_KeccakXofState_4f *self, + Eurydice_slice inputs[1U]) { + libcrux_sha3_generic_keccak_KeccakXofState_4f *uu____0 = self; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_inputs[1U]; + memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice)); + size_t input_remainder_len = + libcrux_sha3_generic_keccak_absorb_full_9d_f8(uu____0, copy_of_inputs); + if (input_remainder_len > (size_t)0U) { + size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t); + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____2 = Eurydice_array_to_subslice2( + self->buf[i0], self->buf_len, self->buf_len + input_remainder_len, + uint8_t); + Eurydice_slice_copy( + uu____2, + Eurydice_slice_subslice_from( + inputs[i0], input_len - input_remainder_len, uint8_t, size_t), + uint8_t); + } + self->buf_len = self->buf_len + input_remainder_len; + } +} + +/** + Shake256 absorb +*/ +/** +This function found in impl +{(libcrux_sha3::portable::incremental::XofAbsorb<136: usize> for +libcrux_sha3::portable::incremental::Shake256Absorb)#2} +*/ +static inline void libcrux_sha3_portable_incremental_absorb_7d( + libcrux_sha3_generic_keccak_KeccakXofState_4f *self, Eurydice_slice input) { + Eurydice_slice buf[1U] = {input}; + libcrux_sha3_generic_keccak_absorb_9d_7b(self, buf); +} + +typedef libcrux_sha3_generic_keccak_KeccakXofState_4f + libcrux_sha3_portable_incremental_Shake256Squeeze; + +/** + Absorb a final block. + + The `inputs` block may be empty. Everything in the `inputs` block beyond + `RATE` bytes is ignored. +*/ +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 136 +- DELIMITER= 31 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_9d_25( + libcrux_sha3_generic_keccak_KeccakXofState_4f *self, + Eurydice_slice inputs[1U]) { + libcrux_sha3_generic_keccak_KeccakXofState_4f *uu____0 = self; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_inputs[1U]; + memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice)); + size_t input_remainder_len = + libcrux_sha3_generic_keccak_absorb_full_9d_f8(uu____0, copy_of_inputs); + size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t); + uint8_t blocks[1U][200U] = {{0U}}; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + if (self->buf_len > (size_t)0U) { + Eurydice_slice uu____2 = Eurydice_array_to_subslice2( + blocks[i0], (size_t)0U, self->buf_len, uint8_t); + Eurydice_slice_copy(uu____2, + Eurydice_array_to_subslice2(self->buf[i0], (size_t)0U, + self->buf_len, uint8_t), + uint8_t); + } + if (input_remainder_len > (size_t)0U) { + Eurydice_slice uu____3 = Eurydice_array_to_subslice2( + blocks[i0], self->buf_len, self->buf_len + input_remainder_len, + uint8_t); + Eurydice_slice_copy( + uu____3, + Eurydice_slice_subslice_from( + inputs[i0], input_len - input_remainder_len, uint8_t, size_t), + uint8_t); + } + blocks[i0][self->buf_len + input_remainder_len] = 31U; + size_t uu____4 = i0; + size_t uu____5 = (size_t)136U - (size_t)1U; + blocks[uu____4][uu____5] = (uint32_t)blocks[uu____4][uu____5] | 128U; + } + uint64_t(*uu____6)[5U] = self->inner.st; + uint8_t uu____7[1U][200U]; + memcpy(uu____7, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full_5a_d20(uu____6, uu____7); + libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); +} + +/** + Shake256 absorb final +*/ +/** +This function found in impl +{(libcrux_sha3::portable::incremental::XofAbsorb<136: usize> for +libcrux_sha3::portable::incremental::Shake256Absorb)#2} +*/ +static inline libcrux_sha3_generic_keccak_KeccakXofState_4f +libcrux_sha3_portable_incremental_absorb_final_7d( + libcrux_sha3_generic_keccak_KeccakXofState_4f self, Eurydice_slice input) { + Eurydice_slice buf[1U] = {input}; + libcrux_sha3_generic_keccak_absorb_final_9d_25(&self, buf); + return self; +} + +/** + An all zero block +*/ +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.zero_block_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 136 +*/ +static inline void libcrux_sha3_generic_keccak_zero_block_9d_e6( + uint8_t ret[136U]) { + ret[0U] = 0U; + ret[1U] = 0U; + ret[2U] = 0U; + ret[3U] = 0U; + ret[4U] = 0U; + ret[5U] = 0U; + ret[6U] = 0U; + ret[7U] = 0U; + ret[8U] = 0U; + ret[9U] = 0U; + ret[10U] = 0U; + ret[11U] = 0U; + ret[12U] = 0U; + ret[13U] = 0U; + ret[14U] = 0U; + ret[15U] = 0U; + ret[16U] = 0U; + ret[17U] = 0U; + ret[18U] = 0U; + ret[19U] = 0U; + ret[20U] = 0U; + ret[21U] = 0U; + ret[22U] = 0U; + ret[23U] = 0U; + ret[24U] = 0U; + ret[25U] = 0U; + ret[26U] = 0U; + ret[27U] = 0U; + ret[28U] = 0U; + ret[29U] = 0U; + ret[30U] = 0U; + ret[31U] = 0U; + ret[32U] = 0U; + ret[33U] = 0U; + ret[34U] = 0U; + ret[35U] = 0U; + ret[36U] = 0U; + ret[37U] = 0U; + ret[38U] = 0U; + ret[39U] = 0U; + ret[40U] = 0U; + ret[41U] = 0U; + ret[42U] = 0U; + ret[43U] = 0U; + ret[44U] = 0U; + ret[45U] = 0U; + ret[46U] = 0U; + ret[47U] = 0U; + ret[48U] = 0U; + ret[49U] = 0U; + ret[50U] = 0U; + ret[51U] = 0U; + ret[52U] = 0U; + ret[53U] = 0U; + ret[54U] = 0U; + ret[55U] = 0U; + ret[56U] = 0U; + ret[57U] = 0U; + ret[58U] = 0U; + ret[59U] = 0U; + ret[60U] = 0U; + ret[61U] = 0U; + ret[62U] = 0U; + ret[63U] = 0U; + ret[64U] = 0U; + ret[65U] = 0U; + ret[66U] = 0U; + ret[67U] = 0U; + ret[68U] = 0U; + ret[69U] = 0U; + ret[70U] = 0U; + ret[71U] = 0U; + ret[72U] = 0U; + ret[73U] = 0U; + ret[74U] = 0U; + ret[75U] = 0U; + ret[76U] = 0U; + ret[77U] = 0U; + ret[78U] = 0U; + ret[79U] = 0U; + ret[80U] = 0U; + ret[81U] = 0U; + ret[82U] = 0U; + ret[83U] = 0U; + ret[84U] = 0U; + ret[85U] = 0U; + ret[86U] = 0U; + ret[87U] = 0U; + ret[88U] = 0U; + ret[89U] = 0U; + ret[90U] = 0U; + ret[91U] = 0U; + ret[92U] = 0U; + ret[93U] = 0U; + ret[94U] = 0U; + ret[95U] = 0U; + ret[96U] = 0U; + ret[97U] = 0U; + ret[98U] = 0U; + ret[99U] = 0U; + ret[100U] = 0U; + ret[101U] = 0U; + ret[102U] = 0U; + ret[103U] = 0U; + ret[104U] = 0U; + ret[105U] = 0U; + ret[106U] = 0U; + ret[107U] = 0U; + ret[108U] = 0U; + ret[109U] = 0U; + ret[110U] = 0U; + ret[111U] = 0U; + ret[112U] = 0U; + ret[113U] = 0U; + ret[114U] = 0U; + ret[115U] = 0U; + ret[116U] = 0U; + ret[117U] = 0U; + ret[118U] = 0U; + ret[119U] = 0U; + ret[120U] = 0U; + ret[121U] = 0U; + ret[122U] = 0U; + ret[123U] = 0U; + ret[124U] = 0U; + ret[125U] = 0U; + ret[126U] = 0U; + ret[127U] = 0U; + ret[128U] = 0U; + ret[129U] = 0U; + ret[130U] = 0U; + ret[131U] = 0U; + ret[132U] = 0U; + ret[133U] = 0U; + ret[134U] = 0U; + ret[135U] = 0U; +} + +/** + Generate a new keccak xof state. +*/ +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.new_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 136 +*/ +static inline libcrux_sha3_generic_keccak_KeccakXofState_4f +libcrux_sha3_generic_keccak_new_9d_7e(void) { + libcrux_sha3_generic_keccak_KeccakXofState_4f lit; + lit.inner = libcrux_sha3_generic_keccak_new_1e_f4(); + uint8_t ret[136U]; + libcrux_sha3_generic_keccak_zero_block_9d_e6(ret); + memcpy(lit.buf[0U], ret, (size_t)136U * sizeof(uint8_t)); + lit.buf_len = (size_t)0U; + lit.sponge = false; + return lit; +} + +/** + Shake256 new state +*/ +/** +This function found in impl +{(libcrux_sha3::portable::incremental::XofAbsorb<136: usize> for +libcrux_sha3::portable::incremental::Shake256Absorb)#2} +*/ +static inline libcrux_sha3_generic_keccak_KeccakXofState_4f +libcrux_sha3_portable_incremental_new_7d(void) { + return libcrux_sha3_generic_keccak_new_9d_7e(); +} + +/** +A monomorphic instance of libcrux_sha3.generic_keccak.KeccakXofState +with types uint64_t +with const generics +- $1size_t +- $168size_t +*/ +typedef struct libcrux_sha3_generic_keccak_KeccakXofState_78_s { + libcrux_sha3_generic_keccak_KeccakState_48 inner; + uint8_t buf[1U][168U]; + size_t buf_len; + bool sponge; +} libcrux_sha3_generic_keccak_KeccakXofState_78; + +typedef libcrux_sha3_generic_keccak_KeccakXofState_78 + libcrux_sha3_portable_incremental_Shake128Absorb; + +/** + Consume the internal buffer and the required amount of the input to pad to + `RATE`. + + Returns the `consumed` bytes from `inputs` if there's enough buffered + content to consume, and `0` otherwise. + If `consumed > 0` is returned, `self.buf` contains a full block to be + loaded. +*/ +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.fill_buffer_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 168 +*/ +static inline size_t libcrux_sha3_generic_keccak_fill_buffer_9d_b00( + libcrux_sha3_generic_keccak_KeccakXofState_78 *self, + Eurydice_slice inputs[1U]) { + size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t); + size_t consumed = (size_t)0U; + if (self->buf_len > (size_t)0U) { + if (self->buf_len + input_len >= (size_t)168U) { + consumed = (size_t)168U - self->buf_len; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)168U, self->buf[i0], self->buf_len, uint8_t, size_t); + Eurydice_slice_copy( + uu____0, + Eurydice_slice_subslice_to(inputs[i0], consumed, uint8_t, size_t), + uint8_t); + } + self->buf_len = self->buf_len + consumed; + } + } + return consumed; +} + +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_full_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 168 +*/ +static inline size_t libcrux_sha3_generic_keccak_absorb_full_9d_f80( + libcrux_sha3_generic_keccak_KeccakXofState_78 *self, + Eurydice_slice inputs[1U]) { + libcrux_sha3_generic_keccak_KeccakXofState_78 *uu____0 = self; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_inputs0[1U]; + memcpy(copy_of_inputs0, inputs, (size_t)1U * sizeof(Eurydice_slice)); + size_t input_consumed = + libcrux_sha3_generic_keccak_fill_buffer_9d_b00(uu____0, copy_of_inputs0); + if (input_consumed > (size_t)0U) { + Eurydice_slice borrowed[1U]; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + uint8_t buf[168U] = {0U}; + borrowed[i] = core_array___Array_T__N__23__as_slice( + (size_t)168U, buf, uint8_t, Eurydice_slice); + } + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + borrowed[i0] = + Eurydice_array_to_slice((size_t)168U, self->buf[i0], uint8_t); + } + uint64_t(*uu____2)[5U] = self->inner.st; + Eurydice_slice uu____3[1U]; + memcpy(uu____3, borrowed, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_load_block_5a_b83(uu____2, uu____3); + libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + self->buf_len = (size_t)0U; + } + size_t input_to_consume = + Eurydice_slice_len(inputs[0U], uint8_t) - input_consumed; + size_t num_blocks = input_to_consume / (size_t)168U; + size_t remainder = input_to_consume % (size_t)168U; + for (size_t i = (size_t)0U; i < num_blocks; i++) { + size_t i0 = i; + uint64_t(*uu____4)[5U] = self->inner.st; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_inputs[1U]; + memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice ret[1U]; + libcrux_sha3_portable_keccak_slice_n_5a( + copy_of_inputs, input_consumed + i0 * (size_t)168U, (size_t)168U, ret); + libcrux_sha3_portable_keccak_load_block_5a_b83(uu____4, ret); + libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + } + return remainder; +} + +/** + Absorb + + This function takes any number of bytes to absorb and buffers if it's not + enough. The function assumes that all input slices in `blocks` have the same + length. + + Only a multiple of `RATE` blocks are absorbed. + For the remaining bytes [`absorb_final`] needs to be called. + + This works best with relatively small `inputs`. +*/ +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_9d_7b0( + libcrux_sha3_generic_keccak_KeccakXofState_78 *self, + Eurydice_slice inputs[1U]) { + libcrux_sha3_generic_keccak_KeccakXofState_78 *uu____0 = self; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_inputs[1U]; + memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice)); + size_t input_remainder_len = + libcrux_sha3_generic_keccak_absorb_full_9d_f80(uu____0, copy_of_inputs); + if (input_remainder_len > (size_t)0U) { + size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t); + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + Eurydice_slice uu____2 = Eurydice_array_to_subslice2( + self->buf[i0], self->buf_len, self->buf_len + input_remainder_len, + uint8_t); + Eurydice_slice_copy( + uu____2, + Eurydice_slice_subslice_from( + inputs[i0], input_len - input_remainder_len, uint8_t, size_t), + uint8_t); + } + self->buf_len = self->buf_len + input_remainder_len; + } +} + +/** +This function found in impl +{(libcrux_sha3::portable::incremental::XofAbsorb<168: usize> for +libcrux_sha3::portable::incremental::Shake128Absorb)} +*/ +static inline void libcrux_sha3_portable_incremental_absorb_1c( + libcrux_sha3_generic_keccak_KeccakXofState_78 *self, Eurydice_slice input) { + Eurydice_slice buf[1U] = {input}; + libcrux_sha3_generic_keccak_absorb_9d_7b0(self, buf); +} + +typedef libcrux_sha3_generic_keccak_KeccakXofState_78 + libcrux_sha3_portable_incremental_Shake128Squeeze; + +/** + Absorb a final block. + + The `inputs` block may be empty. Everything in the `inputs` block beyond + `RATE` bytes is ignored. +*/ +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.absorb_final_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 168 +- DELIMITER= 31 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_absorb_final_9d_250( + libcrux_sha3_generic_keccak_KeccakXofState_78 *self, + Eurydice_slice inputs[1U]) { + libcrux_sha3_generic_keccak_KeccakXofState_78 *uu____0 = self; + /* Passing arrays by value in Rust generates a copy in C */ + Eurydice_slice copy_of_inputs[1U]; + memcpy(copy_of_inputs, inputs, (size_t)1U * sizeof(Eurydice_slice)); + size_t input_remainder_len = + libcrux_sha3_generic_keccak_absorb_full_9d_f80(uu____0, copy_of_inputs); + size_t input_len = Eurydice_slice_len(inputs[0U], uint8_t); + uint8_t blocks[1U][200U] = {{0U}}; + for (size_t i = (size_t)0U; i < (size_t)1U; i++) { + size_t i0 = i; + if (self->buf_len > (size_t)0U) { + Eurydice_slice uu____2 = Eurydice_array_to_subslice2( + blocks[i0], (size_t)0U, self->buf_len, uint8_t); + Eurydice_slice_copy(uu____2, + Eurydice_array_to_subslice2(self->buf[i0], (size_t)0U, + self->buf_len, uint8_t), + uint8_t); + } + if (input_remainder_len > (size_t)0U) { + Eurydice_slice uu____3 = Eurydice_array_to_subslice2( + blocks[i0], self->buf_len, self->buf_len + input_remainder_len, + uint8_t); + Eurydice_slice_copy( + uu____3, + Eurydice_slice_subslice_from( + inputs[i0], input_len - input_remainder_len, uint8_t, size_t), + uint8_t); + } + blocks[i0][self->buf_len + input_remainder_len] = 31U; + size_t uu____4 = i0; + size_t uu____5 = (size_t)168U - (size_t)1U; + blocks[uu____4][uu____5] = (uint32_t)blocks[uu____4][uu____5] | 128U; + } + uint64_t(*uu____6)[5U] = self->inner.st; + uint8_t uu____7[1U][200U]; + memcpy(uu____7, blocks, (size_t)1U * sizeof(uint8_t[200U])); + libcrux_sha3_portable_keccak_load_block_full_5a_d21(uu____6, uu____7); + libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); +} + +/** +This function found in impl +{(libcrux_sha3::portable::incremental::XofAbsorb<168: usize> for +libcrux_sha3::portable::incremental::Shake128Absorb)} +*/ +static inline libcrux_sha3_generic_keccak_KeccakXofState_78 +libcrux_sha3_portable_incremental_absorb_final_1c( + libcrux_sha3_generic_keccak_KeccakXofState_78 self, Eurydice_slice input) { + Eurydice_slice buf[1U] = {input}; + libcrux_sha3_generic_keccak_absorb_final_9d_250(&self, buf); + return self; +} + +/** + An all zero block +*/ +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.zero_block_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 168 +*/ +static inline void libcrux_sha3_generic_keccak_zero_block_9d_e60( + uint8_t ret[168U]) { + ret[0U] = 0U; + ret[1U] = 0U; + ret[2U] = 0U; + ret[3U] = 0U; + ret[4U] = 0U; + ret[5U] = 0U; + ret[6U] = 0U; + ret[7U] = 0U; + ret[8U] = 0U; + ret[9U] = 0U; + ret[10U] = 0U; + ret[11U] = 0U; + ret[12U] = 0U; + ret[13U] = 0U; + ret[14U] = 0U; + ret[15U] = 0U; + ret[16U] = 0U; + ret[17U] = 0U; + ret[18U] = 0U; + ret[19U] = 0U; + ret[20U] = 0U; + ret[21U] = 0U; + ret[22U] = 0U; + ret[23U] = 0U; + ret[24U] = 0U; + ret[25U] = 0U; + ret[26U] = 0U; + ret[27U] = 0U; + ret[28U] = 0U; + ret[29U] = 0U; + ret[30U] = 0U; + ret[31U] = 0U; + ret[32U] = 0U; + ret[33U] = 0U; + ret[34U] = 0U; + ret[35U] = 0U; + ret[36U] = 0U; + ret[37U] = 0U; + ret[38U] = 0U; + ret[39U] = 0U; + ret[40U] = 0U; + ret[41U] = 0U; + ret[42U] = 0U; + ret[43U] = 0U; + ret[44U] = 0U; + ret[45U] = 0U; + ret[46U] = 0U; + ret[47U] = 0U; + ret[48U] = 0U; + ret[49U] = 0U; + ret[50U] = 0U; + ret[51U] = 0U; + ret[52U] = 0U; + ret[53U] = 0U; + ret[54U] = 0U; + ret[55U] = 0U; + ret[56U] = 0U; + ret[57U] = 0U; + ret[58U] = 0U; + ret[59U] = 0U; + ret[60U] = 0U; + ret[61U] = 0U; + ret[62U] = 0U; + ret[63U] = 0U; + ret[64U] = 0U; + ret[65U] = 0U; + ret[66U] = 0U; + ret[67U] = 0U; + ret[68U] = 0U; + ret[69U] = 0U; + ret[70U] = 0U; + ret[71U] = 0U; + ret[72U] = 0U; + ret[73U] = 0U; + ret[74U] = 0U; + ret[75U] = 0U; + ret[76U] = 0U; + ret[77U] = 0U; + ret[78U] = 0U; + ret[79U] = 0U; + ret[80U] = 0U; + ret[81U] = 0U; + ret[82U] = 0U; + ret[83U] = 0U; + ret[84U] = 0U; + ret[85U] = 0U; + ret[86U] = 0U; + ret[87U] = 0U; + ret[88U] = 0U; + ret[89U] = 0U; + ret[90U] = 0U; + ret[91U] = 0U; + ret[92U] = 0U; + ret[93U] = 0U; + ret[94U] = 0U; + ret[95U] = 0U; + ret[96U] = 0U; + ret[97U] = 0U; + ret[98U] = 0U; + ret[99U] = 0U; + ret[100U] = 0U; + ret[101U] = 0U; + ret[102U] = 0U; + ret[103U] = 0U; + ret[104U] = 0U; + ret[105U] = 0U; + ret[106U] = 0U; + ret[107U] = 0U; + ret[108U] = 0U; + ret[109U] = 0U; + ret[110U] = 0U; + ret[111U] = 0U; + ret[112U] = 0U; + ret[113U] = 0U; + ret[114U] = 0U; + ret[115U] = 0U; + ret[116U] = 0U; + ret[117U] = 0U; + ret[118U] = 0U; + ret[119U] = 0U; + ret[120U] = 0U; + ret[121U] = 0U; + ret[122U] = 0U; + ret[123U] = 0U; + ret[124U] = 0U; + ret[125U] = 0U; + ret[126U] = 0U; + ret[127U] = 0U; + ret[128U] = 0U; + ret[129U] = 0U; + ret[130U] = 0U; + ret[131U] = 0U; + ret[132U] = 0U; + ret[133U] = 0U; + ret[134U] = 0U; + ret[135U] = 0U; + ret[136U] = 0U; + ret[137U] = 0U; + ret[138U] = 0U; + ret[139U] = 0U; + ret[140U] = 0U; + ret[141U] = 0U; + ret[142U] = 0U; + ret[143U] = 0U; + ret[144U] = 0U; + ret[145U] = 0U; + ret[146U] = 0U; + ret[147U] = 0U; + ret[148U] = 0U; + ret[149U] = 0U; + ret[150U] = 0U; + ret[151U] = 0U; + ret[152U] = 0U; + ret[153U] = 0U; + ret[154U] = 0U; + ret[155U] = 0U; + ret[156U] = 0U; + ret[157U] = 0U; + ret[158U] = 0U; + ret[159U] = 0U; + ret[160U] = 0U; + ret[161U] = 0U; + ret[162U] = 0U; + ret[163U] = 0U; + ret[164U] = 0U; + ret[165U] = 0U; + ret[166U] = 0U; + ret[167U] = 0U; +} + +/** + Generate a new keccak xof state. +*/ +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.new_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 168 +*/ +static inline libcrux_sha3_generic_keccak_KeccakXofState_78 +libcrux_sha3_generic_keccak_new_9d_7e0(void) { + libcrux_sha3_generic_keccak_KeccakXofState_78 lit; + lit.inner = libcrux_sha3_generic_keccak_new_1e_f4(); + uint8_t ret[168U]; + libcrux_sha3_generic_keccak_zero_block_9d_e60(ret); + memcpy(lit.buf[0U], ret, (size_t)168U * sizeof(uint8_t)); + lit.buf_len = (size_t)0U; + lit.sponge = false; + return lit; +} + +/** +This function found in impl +{(libcrux_sha3::portable::incremental::XofAbsorb<168: usize> for +libcrux_sha3::portable::incremental::Shake128Absorb)} +*/ +static inline libcrux_sha3_generic_keccak_KeccakXofState_78 +libcrux_sha3_portable_incremental_new_1c(void) { + return libcrux_sha3_generic_keccak_new_9d_7e0(); +} + +/** + `out` has the exact size we want here. It must be less than or equal to `RATE`. +*/ +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_5a +with const generics +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_5a_1c( + uint64_t (*state)[5U], Eurydice_slice out[1U]) { + size_t num_full_blocks = Eurydice_slice_len(out[0U], uint8_t) / (size_t)8U; + size_t last_block_len = Eurydice_slice_len(out[0U], uint8_t) % (size_t)8U; + for (size_t i = (size_t)0U; i < num_full_blocks; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_slice_subslice2( + out[0U], i0 * (size_t)8U, i0 * (size_t)8U + (size_t)8U, uint8_t); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(state[i0 / (size_t)5U][i0 % (size_t)5U], ret); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); + } + if (last_block_len != (size_t)0U) { + Eurydice_slice uu____1 = Eurydice_slice_subslice2( + out[0U], num_full_blocks * (size_t)8U, + num_full_blocks * (size_t)8U + last_block_len, uint8_t); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes( + state[num_full_blocks / (size_t)5U][num_full_blocks % (size_t)5U], ret); + Eurydice_slice_copy( + uu____1, + Eurydice_array_to_subslice2(ret, (size_t)0U, last_block_len, uint8_t), + uint8_t); + } +} + +/** + Squeeze `N` x `LEN` bytes. +*/ +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 136 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_9d_96( + libcrux_sha3_generic_keccak_KeccakXofState_4f *self, + Eurydice_slice out[1U]) { + if (self->sponge) { + libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + } + size_t out_len = Eurydice_slice_len(out[0U], uint8_t); + size_t blocks = out_len / (size_t)136U; + size_t last = out_len - out_len % (size_t)136U; + size_t mid; + if ((size_t)136U >= out_len) { + mid = out_len; + } else { + mid = (size_t)136U; + } + Eurydice_slice_uint8_t_1size_t__x2 uu____0 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, mid); + Eurydice_slice out00[1U]; + memcpy(out00, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice out_rest[1U]; + memcpy(out_rest, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_store_5a_1c(self->inner.st, out00); + core_ops_range_Range_b3 iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( + (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range_b3, core_ops_range_Range_b3); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, Option_b3) + .tag == None) { + break; + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____1 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(out_rest, + (size_t)136U); + Eurydice_slice out0[1U]; + memcpy(out0, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice tmp[1U]; + memcpy(tmp, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + libcrux_sha3_portable_keccak_store_5a_1c(self->inner.st, out0); + memcpy(out_rest, tmp, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < out_len) { + libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + libcrux_sha3_portable_keccak_store_5a_1c(self->inner.st, out_rest); + } + self->sponge = true; +} + +/** + Shake256 squeeze +*/ +/** +This function found in impl +{(libcrux_sha3::portable::incremental::XofSqueeze<136: usize> for +libcrux_sha3::portable::incremental::Shake256Squeeze)#3} +*/ +static inline void libcrux_sha3_portable_incremental_squeeze_8a( + libcrux_sha3_generic_keccak_KeccakXofState_4f *self, Eurydice_slice out) { + Eurydice_slice buf[1U] = {out}; + libcrux_sha3_generic_keccak_squeeze_9d_96(self, buf); +} + +/** + `out` has the exact size we want here. It must be less than or equal to `RATE`. +*/ +/** +This function found in impl {(libcrux_sha3::traits::internal::KeccakItem<1: +usize> for u64)} +*/ +/** +A monomorphic instance of libcrux_sha3.portable_keccak.store_5a +with const generics +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_portable_keccak_store_5a_1c0( + uint64_t (*state)[5U], Eurydice_slice out[1U]) { + size_t num_full_blocks = Eurydice_slice_len(out[0U], uint8_t) / (size_t)8U; + size_t last_block_len = Eurydice_slice_len(out[0U], uint8_t) % (size_t)8U; + for (size_t i = (size_t)0U; i < num_full_blocks; i++) { + size_t i0 = i; + Eurydice_slice uu____0 = Eurydice_slice_subslice2( + out[0U], i0 * (size_t)8U, i0 * (size_t)8U + (size_t)8U, uint8_t); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes(state[i0 / (size_t)5U][i0 % (size_t)5U], ret); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)8U, ret, uint8_t), uint8_t); + } + if (last_block_len != (size_t)0U) { + Eurydice_slice uu____1 = Eurydice_slice_subslice2( + out[0U], num_full_blocks * (size_t)8U, + num_full_blocks * (size_t)8U + last_block_len, uint8_t); + uint8_t ret[8U]; + core_num__u64_9__to_le_bytes( + state[num_full_blocks / (size_t)5U][num_full_blocks % (size_t)5U], ret); + Eurydice_slice_copy( + uu____1, + Eurydice_array_to_subslice2(ret, (size_t)0U, last_block_len, uint8_t), + uint8_t); + } +} + +/** + Squeeze `N` x `LEN` bytes. +*/ +/** +This function found in impl {libcrux_sha3::generic_keccak::KeccakXofState[TraitClause@0]#2} +*/ +/** +A monomorphic instance of libcrux_sha3.generic_keccak.squeeze_9d +with types uint64_t +with const generics +- PARALLEL_LANES= 1 +- RATE= 168 +*/ +static KRML_MUSTINLINE void libcrux_sha3_generic_keccak_squeeze_9d_960( + libcrux_sha3_generic_keccak_KeccakXofState_78 *self, + Eurydice_slice out[1U]) { + if (self->sponge) { + libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + } + size_t out_len = Eurydice_slice_len(out[0U], uint8_t); + size_t blocks = out_len / (size_t)168U; + size_t last = out_len - out_len % (size_t)168U; + size_t mid; + if ((size_t)168U >= out_len) { + mid = out_len; + } else { + mid = (size_t)168U; + } + Eurydice_slice_uint8_t_1size_t__x2 uu____0 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(out, mid); + Eurydice_slice out00[1U]; + memcpy(out00, uu____0.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice out_rest[1U]; + memcpy(out_rest, uu____0.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_portable_keccak_store_5a_1c0(self->inner.st, out00); + core_ops_range_Range_b3 iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( + (CLITERAL(core_ops_range_Range_b3){.start = (size_t)1U, + .end = blocks}), + core_ops_range_Range_b3, core_ops_range_Range_b3); + while (true) { + if (core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, Option_b3) + .tag == None) { + break; + } else { + Eurydice_slice_uint8_t_1size_t__x2 uu____1 = + libcrux_sha3_portable_keccak_split_at_mut_n_5a(out_rest, + (size_t)168U); + Eurydice_slice out0[1U]; + memcpy(out0, uu____1.fst, (size_t)1U * sizeof(Eurydice_slice)); + Eurydice_slice tmp[1U]; + memcpy(tmp, uu____1.snd, (size_t)1U * sizeof(Eurydice_slice)); + libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + libcrux_sha3_portable_keccak_store_5a_1c0(self->inner.st, out0); + memcpy(out_rest, tmp, (size_t)1U * sizeof(Eurydice_slice)); + } + } + if (last < out_len) { + libcrux_sha3_generic_keccak_keccakf1600_21(&self->inner); + libcrux_sha3_portable_keccak_store_5a_1c0(self->inner.st, out_rest); + } + self->sponge = true; +} + +/** + Shake128 squeeze +*/ +/** +This function found in impl +{(libcrux_sha3::portable::incremental::XofSqueeze<168: usize> for +libcrux_sha3::portable::incremental::Shake128Squeeze)#1} +*/ +static inline void libcrux_sha3_portable_incremental_squeeze_10( + libcrux_sha3_generic_keccak_KeccakXofState_78 *self, Eurydice_slice out) { + Eurydice_slice buf[1U] = {out}; + libcrux_sha3_generic_keccak_squeeze_9d_960(self, buf); +} + +/** +This function found in impl {(core::clone::Clone for +libcrux_sha3::portable::KeccakState)} +*/ +static inline libcrux_sha3_generic_keccak_KeccakState_48 +libcrux_sha3_portable_clone_3d( + libcrux_sha3_generic_keccak_KeccakState_48 *self) { + return self[0U]; +} + +/** +This function found in impl {(core::convert::From for +u32)#1} +*/ +static inline uint32_t libcrux_sha3_from_eb(libcrux_sha3_Algorithm v) { + uint32_t uu____0; + switch (v) { + case libcrux_sha3_Sha224: { + uu____0 = 1U; + break; + } + case libcrux_sha3_Sha256: { + uu____0 = 2U; + break; + } + case libcrux_sha3_Sha384: { + uu____0 = 3U; + break; + } + case libcrux_sha3_Sha512: { + uu____0 = 4U; + break; + } + default: { + KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, + __LINE__); + KRML_HOST_EXIT(253U); + } + } + return uu____0; +} + +/** +This function found in impl {(core::convert::From for +libcrux_sha3::Algorithm)} +*/ +static inline libcrux_sha3_Algorithm libcrux_sha3_from_2d(uint32_t v) { + libcrux_sha3_Algorithm uu____0; + switch (v) { + case 1U: { + uu____0 = libcrux_sha3_Sha224; + break; + } + case 2U: { + uu____0 = libcrux_sha3_Sha256; + break; + } + case 3U: { + uu____0 = libcrux_sha3_Sha384; + break; + } + case 4U: { + uu____0 = libcrux_sha3_Sha512; + break; + } + default: { + KRML_HOST_EPRINTF("KaRaMeL abort at %s:%d\n%s\n", __FILE__, __LINE__, + "panic!"); + KRML_HOST_EXIT(255U); + } + } + return uu____0; +} + +typedef uint8_t libcrux_sha3_Sha3_512Digest[64U]; + +typedef uint8_t libcrux_sha3_Sha3_384Digest[48U]; + +typedef uint8_t libcrux_sha3_Sha3_256Digest[32U]; + +typedef uint8_t libcrux_sha3_Sha3_224Digest[28U]; + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_sha3_portable_H_DEFINED +#endif + +/* from libcrux/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h */ +/* + * SPDX-FileCopyrightText: 2024 Cryspen Sarl + * + * SPDX-License-Identifier: MIT or Apache-2.0 + * + * This code was generated with the following revisions: + * Charon: 6b5e110342a771a3e1c739b10294b1778e4be8b4 + * Eurydice: 31be7d65ca5d6acdacfb33652e478d24dd85c1cb + * Karamel: 3205d3365ea2790b02368f79fcee38e38d0b5908 + * F*: a32b316e521fa4f239b610ec8f1d15e78d62cbe8-dirty + * Libcrux: 4ad532b206174114dd4140b718e7794a28fc59ee + */ + +#ifndef __libcrux_mlkem768_portable_H +#define __libcrux_mlkem768_portable_H + +#if defined(__cplusplus) +extern "C" { +#endif + + +#define LIBCRUX_ML_KEM_HASH_FUNCTIONS_BLOCK_SIZE ((size_t)168U) + +#define LIBCRUX_ML_KEM_HASH_FUNCTIONS_THREE_BLOCKS \ + (LIBCRUX_ML_KEM_HASH_FUNCTIONS_BLOCK_SIZE * (size_t)3U) + +static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_G( + Eurydice_slice input, uint8_t ret[64U]) { + uint8_t digest[64U] = {0U}; + libcrux_sha3_portable_sha512( + Eurydice_array_to_slice((size_t)64U, digest, uint8_t), input); + memcpy(ret, digest, (size_t)64U * sizeof(uint8_t)); +} + +static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_H( + Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_sha256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t), input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +#define LIBCRUX_ML_KEM_IND_CCA_ENCAPS_SEED_SIZE \ + (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) + +#define LIBCRUX_ML_KEM_IND_CCA_KEY_GENERATION_SEED_SIZE \ + (LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE + \ + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) + +typedef uint8_t libcrux_ml_kem_ind_cca_MlKemSharedSecret[32U]; + +static const int16_t libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[128U] = + {(int16_t)-1044, (int16_t)-758, (int16_t)-359, (int16_t)-1517, + (int16_t)1493, (int16_t)1422, (int16_t)287, (int16_t)202, + (int16_t)-171, (int16_t)622, (int16_t)1577, (int16_t)182, + (int16_t)962, (int16_t)-1202, (int16_t)-1474, (int16_t)1468, + (int16_t)573, (int16_t)-1325, (int16_t)264, (int16_t)383, + (int16_t)-829, (int16_t)1458, (int16_t)-1602, (int16_t)-130, + (int16_t)-681, (int16_t)1017, (int16_t)732, (int16_t)608, + (int16_t)-1542, (int16_t)411, (int16_t)-205, (int16_t)-1571, + (int16_t)1223, (int16_t)652, (int16_t)-552, (int16_t)1015, + (int16_t)-1293, (int16_t)1491, (int16_t)-282, (int16_t)-1544, + (int16_t)516, (int16_t)-8, (int16_t)-320, (int16_t)-666, + (int16_t)-1618, (int16_t)-1162, (int16_t)126, (int16_t)1469, + (int16_t)-853, (int16_t)-90, (int16_t)-271, (int16_t)830, + (int16_t)107, (int16_t)-1421, (int16_t)-247, (int16_t)-951, + (int16_t)-398, (int16_t)961, (int16_t)-1508, (int16_t)-725, + (int16_t)448, (int16_t)-1065, (int16_t)677, (int16_t)-1275, + (int16_t)-1103, (int16_t)430, (int16_t)555, (int16_t)843, + (int16_t)-1251, (int16_t)871, (int16_t)1550, (int16_t)105, + (int16_t)422, (int16_t)587, (int16_t)177, (int16_t)-235, + (int16_t)-291, (int16_t)-460, (int16_t)1574, (int16_t)1653, + (int16_t)-246, (int16_t)778, (int16_t)1159, (int16_t)-147, + (int16_t)-777, (int16_t)1483, (int16_t)-602, (int16_t)1119, + (int16_t)-1590, (int16_t)644, (int16_t)-872, (int16_t)349, + (int16_t)418, (int16_t)329, (int16_t)-156, (int16_t)-75, + (int16_t)817, (int16_t)1097, (int16_t)603, (int16_t)610, + (int16_t)1322, (int16_t)-1285, (int16_t)-1465, (int16_t)384, + (int16_t)-1215, (int16_t)-136, (int16_t)1218, (int16_t)-1335, + (int16_t)-874, (int16_t)220, (int16_t)-1187, (int16_t)-1659, + (int16_t)-1185, (int16_t)-1530, (int16_t)-1278, (int16_t)794, + (int16_t)-1510, (int16_t)-854, (int16_t)-870, (int16_t)478, + (int16_t)-108, (int16_t)-308, (int16_t)996, (int16_t)991, + (int16_t)958, (int16_t)-1460, (int16_t)1522, (int16_t)1628}; + +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR ((size_t)16U) + +#define LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / \ + LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR) + +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS ((int16_t)3329) + +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS \ + ((int16_t)1353) + +#define LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R \ + (62209U) + +typedef struct libcrux_ml_kem_vector_portable_vector_type_PortableVector_s { + int16_t elements[16U]; +} libcrux_ml_kem_vector_portable_vector_type_PortableVector; + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_vector_type_from_i16_array( + Eurydice_slice array) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector lit; + int16_t ret[16U]; + Result_c0 dst; + Eurydice_slice_to_array2( + &dst, Eurydice_slice_subslice2(array, (size_t)0U, (size_t)16U, int16_t), + Eurydice_slice, int16_t[16U]); + unwrap_41_f9(dst, ret); + memcpy(lit.elements, ret, (size_t)16U * sizeof(int16_t)); + return lit; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_from_i16_array_0d(Eurydice_slice array) { + return libcrux_ml_kem_vector_portable_vector_type_from_i16_array(array); +} + +typedef struct uint8_t_x11_s { + uint8_t fst; + uint8_t snd; + uint8_t thd; + uint8_t f3; + uint8_t f4; + uint8_t f5; + uint8_t f6; + uint8_t f7; + uint8_t f8; + uint8_t f9; + uint8_t f10; +} uint8_t_x11; + +static KRML_MUSTINLINE uint8_t_x11 +libcrux_ml_kem_vector_portable_serialize_serialize_11_int(Eurydice_slice v) { + uint8_t r0 = (uint8_t)Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *); + uint8_t r1 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t, + int16_t *) & + (int16_t)31) + << 3U | + (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, + int16_t *) >> + 8U); + uint8_t r2 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t, + int16_t *) & + (int16_t)3) + << 6U | + (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t, + int16_t *) >> + 5U); + uint8_t r3 = + (uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *) >> 2U & + (int16_t)255); + uint8_t r4 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t, + int16_t *) & + (int16_t)127) + << 1U | + (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t, + int16_t *) >> + 10U); + uint8_t r5 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)4U, int16_t, + int16_t *) & + (int16_t)15) + << 4U | + (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t, + int16_t *) >> + 7U); + uint8_t r6 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)5U, int16_t, + int16_t *) & + (int16_t)1) + << 7U | + (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)4U, int16_t, + int16_t *) >> + 4U); + uint8_t r7 = + (uint8_t)(Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *) >> 1U & + (int16_t)255); + uint8_t r8 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)6U, int16_t, + int16_t *) & + (int16_t)63) + << 2U | + (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)5U, int16_t, + int16_t *) >> + 9U); + uint8_t r9 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)7U, int16_t, + int16_t *) & + (int16_t)7) + << 5U | + (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)6U, int16_t, + int16_t *) >> + 6U); + uint8_t r10 = + (uint8_t)(Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *) >> 3U); + return (CLITERAL(uint8_t_x11){.fst = r0, + .snd = r1, + .thd = r2, + .f3 = r3, + .f4 = r4, + .f5 = r5, + .f6 = r6, + .f7 = r7, + .f8 = r8, + .f9 = r9, + .f10 = r10}); +} + +static KRML_MUSTINLINE void +libcrux_ml_kem_vector_portable_serialize_serialize_11( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, + uint8_t ret[22U]) { + uint8_t_x11 r0_10 = libcrux_ml_kem_vector_portable_serialize_serialize_11_int( + Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)8U, int16_t)); + uint8_t_x11 r11_21 = + libcrux_ml_kem_vector_portable_serialize_serialize_11_int( + Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)16U, + int16_t)); + uint8_t result[22U] = {0U}; + result[0U] = r0_10.fst; + result[1U] = r0_10.snd; + result[2U] = r0_10.thd; + result[3U] = r0_10.f3; + result[4U] = r0_10.f4; + result[5U] = r0_10.f5; + result[6U] = r0_10.f6; + result[7U] = r0_10.f7; + result[8U] = r0_10.f8; + result[9U] = r0_10.f9; + result[10U] = r0_10.f10; + result[11U] = r11_21.fst; + result[12U] = r11_21.snd; + result[13U] = r11_21.thd; + result[14U] = r11_21.f3; + result[15U] = r11_21.f4; + result[16U] = r11_21.f5; + result[17U] = r11_21.f6; + result[18U] = r11_21.f7; + result[19U] = r11_21.f8; + result[20U] = r11_21.f9; + result[21U] = r11_21.f10; + memcpy(ret, result, (size_t)22U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline void libcrux_ml_kem_vector_portable_serialize_11_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, + uint8_t ret[22U]) { + libcrux_ml_kem_vector_portable_serialize_serialize_11(a, ret); +} + +typedef struct int16_t_x8_s { + int16_t fst; + int16_t snd; + int16_t thd; + int16_t f3; + int16_t f4; + int16_t f5; + int16_t f6; + int16_t f7; +} int16_t_x8; + +static KRML_MUSTINLINE int16_t_x8 +libcrux_ml_kem_vector_portable_serialize_deserialize_11_int( + Eurydice_slice bytes) { + int16_t r0 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) & + (int16_t)7) + << 8U | + (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *); + int16_t r1 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) & + (int16_t)63) + << 5U | + (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) >> + 3U; + int16_t r2 = + (((int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *) & + (int16_t)1) + << 10U | + (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) + << 2U) | + (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) >> + 6U; + int16_t r3 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *) & + (int16_t)15) + << 7U | + (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *) >> + 1U; + int16_t r4 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *) & + (int16_t)127) + << 4U | + (int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *) >> + 4U; + int16_t r5 = + (((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *) & + (int16_t)3) + << 9U | + (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *) + << 1U) | + (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *) >> + 7U; + int16_t r6 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *) & + (int16_t)31) + << 6U | + (int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *) >> + 2U; + int16_t r7 = + (int16_t)Eurydice_slice_index(bytes, (size_t)10U, uint8_t, uint8_t *) + << 3U | + (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *) >> + 5U; + return (CLITERAL(int16_t_x8){.fst = r0, + .snd = r1, + .thd = r2, + .f3 = r3, + .f4 = r4, + .f5 = r5, + .f6 = r6, + .f7 = r7}); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_vector_type_zero(void) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector lit; + lit.elements[0U] = (int16_t)0; + lit.elements[1U] = (int16_t)0; + lit.elements[2U] = (int16_t)0; + lit.elements[3U] = (int16_t)0; + lit.elements[4U] = (int16_t)0; + lit.elements[5U] = (int16_t)0; + lit.elements[6U] = (int16_t)0; + lit.elements[7U] = (int16_t)0; + lit.elements[8U] = (int16_t)0; + lit.elements[9U] = (int16_t)0; + lit.elements[10U] = (int16_t)0; + lit.elements[11U] = (int16_t)0; + lit.elements[12U] = (int16_t)0; + lit.elements[13U] = (int16_t)0; + lit.elements[14U] = (int16_t)0; + lit.elements[15U] = (int16_t)0; + return lit; +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_serialize_deserialize_11(Eurydice_slice bytes) { + int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_11_int( + Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)11U, uint8_t)); + int16_t_x8 v8_15 = + libcrux_ml_kem_vector_portable_serialize_deserialize_11_int( + Eurydice_slice_subslice2(bytes, (size_t)11U, (size_t)22U, uint8_t)); + libcrux_ml_kem_vector_portable_vector_type_PortableVector v = + libcrux_ml_kem_vector_portable_vector_type_zero(); + v.elements[0U] = v0_7.fst; + v.elements[1U] = v0_7.snd; + v.elements[2U] = v0_7.thd; + v.elements[3U] = v0_7.f3; + v.elements[4U] = v0_7.f4; + v.elements[5U] = v0_7.f5; + v.elements[6U] = v0_7.f6; + v.elements[7U] = v0_7.f7; + v.elements[8U] = v8_15.fst; + v.elements[9U] = v8_15.snd; + v.elements[10U] = v8_15.thd; + v.elements[11U] = v8_15.f3; + v.elements[12U] = v8_15.f4; + v.elements[13U] = v8_15.f5; + v.elements[14U] = v8_15.f6; + v.elements[15U] = v8_15.f7; + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_deserialize_11_0d(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_serialize_deserialize_11(a); +} + +static KRML_MUSTINLINE void +libcrux_ml_kem_vector_portable_vector_type_to_i16_array( + libcrux_ml_kem_vector_portable_vector_type_PortableVector x, + int16_t ret[16U]) { + memcpy(ret, x.elements, (size_t)16U * sizeof(int16_t)); +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline void libcrux_ml_kem_vector_portable_to_i16_array_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector x, + int16_t ret[16U]) { + libcrux_ml_kem_vector_portable_vector_type_to_i16_array(x, ret); +} + +static const uint8_t + libcrux_ml_kem_vector_rej_sample_table_REJECTION_SAMPLE_SHUFFLE_TABLE + [256U][16U] = {{255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 255U, + 255U, 255U, 255U}, + {12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 255U, + 255U, 255U, 255U}, + {10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, + 13U, 255U, 255U}, + {14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 14U, 15U, 255U, + 255U, 255U, 255U}, + {10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 14U, + 15U, 255U, 255U}, + {12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, 255U, 255U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, 255U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 255U, + 255U, 255U, 255U, 255U, 255U}, + {0U, 1U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 2U, 3U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, + 255U, 255U, 255U, 255U}, + {0U, 1U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, + 15U, 255U, 255U}, + {0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, + 13U, 14U, 15U}}; + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_ZERO_0d(void) { + return libcrux_ml_kem_vector_portable_vector_type_zero(); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_arithmetic_add( + libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs, + libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + size_t uu____0 = i0; + lhs.elements[uu____0] = lhs.elements[uu____0] + rhs->elements[i0]; + } + return lhs; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_add_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs, + libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs) { + return libcrux_ml_kem_vector_portable_arithmetic_add(lhs, rhs); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_arithmetic_sub( + libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs, + libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + size_t uu____0 = i0; + lhs.elements[uu____0] = lhs.elements[uu____0] - rhs->elements[i0]; + } + return lhs; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_sub_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector lhs, + libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs) { + return libcrux_ml_kem_vector_portable_arithmetic_sub(lhs, rhs); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_arithmetic_multiply_by_constant( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t c) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + size_t uu____0 = i0; + v.elements[uu____0] = v.elements[uu____0] * c; + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_multiply_by_constant_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t c) { + return libcrux_ml_kem_vector_portable_arithmetic_multiply_by_constant(v, c); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_arithmetic_bitwise_and_with_constant( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t c) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + size_t uu____0 = i0; + v.elements[uu____0] = v.elements[uu____0] & c; + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_bitwise_and_with_constant_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t c) { + return libcrux_ml_kem_vector_portable_arithmetic_bitwise_and_with_constant(v, + c); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_arithmetic_cond_subtract_3329( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + core_ops_range_Range_b3 iter = + core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter( + (CLITERAL(core_ops_range_Range_b3){ + .start = (size_t)0U, + .end = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR}), + core_ops_range_Range_b3, core_ops_range_Range_b3); + while (true) { + Option_b3 uu____0 = + core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A___6__next( + &iter, size_t, Option_b3); + if (!(uu____0.tag == None)) { + size_t i = uu____0.f0; + if (v.elements[i] >= (int16_t)3329) { + size_t uu____1 = i; + v.elements[uu____1] = v.elements[uu____1] - (int16_t)3329; + } + continue; + } + return v; + } +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_cond_subtract_3329_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + return libcrux_ml_kem_vector_portable_arithmetic_cond_subtract_3329(v); +} + +#define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_MULTIPLIER \ + ((int32_t)20159) + +#define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_SHIFT ((int32_t)26) + +#define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_R \ + ((int32_t)1 << (uint32_t) \ + LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_SHIFT) + +/** + Signed Barrett Reduction + + Given an input `value`, `barrett_reduce` outputs a representative `result` + such that: + + - result ≡ value (mod FIELD_MODULUS) + - the absolute value of `result` is bound as follows: + + `|result| ≤ FIELD_MODULUS / 2 · (|value|/BARRETT_R + 1) + + In particular, if `|value| < BARRETT_R`, then `|result| < FIELD_MODULUS`. +*/ +static inline int16_t +libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element( + int16_t value) { + int32_t t = (int32_t)value * + LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_MULTIPLIER + + (LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_R >> 1U); + int16_t quotient = + (int16_t)(t >> + (uint32_t) + LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_BARRETT_SHIFT); + return value - quotient * LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + v.elements[i0] = + libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element( + v.elements[i0]); + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_barrett_reduce_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + return libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce(v); +} + +#define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT (16U) + +#define LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_R \ + ((int32_t)1 << (uint32_t) \ + LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT) + +/** + Signed Montgomery Reduction + + Given an input `value`, `montgomery_reduce` outputs a representative `o` + such that: + + - o ≡ value · MONTGOMERY_R^(-1) (mod FIELD_MODULUS) + - the absolute value of `o` is bound as follows: + + `|result| ≤ (|value| / MONTGOMERY_R) + (FIELD_MODULUS / 2) + + In particular, if `|value| ≤ FIELD_MODULUS * MONTGOMERY_R`, then `|o| < (3 · + FIELD_MODULUS) / 2`. +*/ +static inline int16_t +libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( + int32_t value) { + int32_t k = + (int32_t)(int16_t)value * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_INVERSE_OF_MODULUS_MOD_MONTGOMERY_R; + int32_t k_times_modulus = + (int32_t)(int16_t)k * (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + int16_t c = + (int16_t)(k_times_modulus >> + (uint32_t) + LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT); + int16_t value_high = + (int16_t)(value >> + (uint32_t) + LIBCRUX_ML_KEM_VECTOR_PORTABLE_ARITHMETIC_MONTGOMERY_SHIFT); + return value_high - c; +} + +/** + If `fe` is some field element 'x' of the Kyber field and `fer` is congruent to + `y · MONTGOMERY_R`, this procedure outputs a value that is congruent to + `x · y`, as follows: + + `fe · fer ≡ x · y · MONTGOMERY_R (mod FIELD_MODULUS)` + + `montgomery_reduce` takes the value `x · y · MONTGOMERY_R` and outputs a + representative `x · y · MONTGOMERY_R * MONTGOMERY_R^{-1} ≡ x · y (mod + FIELD_MODULUS)`. +*/ +static KRML_MUSTINLINE int16_t +libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer( + int16_t fe, int16_t fer) { + return libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( + (int32_t)fe * (int32_t)fer); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_by_constant( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t c) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + v.elements[i0] = + libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer( + v.elements[i0], c); + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t r) { + return libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_by_constant( + v, r); +} + +/** + The `compress_*` functions implement the `Compress` function specified in the + NIST FIPS 203 standard (Page 18, Expression 4.5), which is defined as: + + ```plaintext + Compress_d: ℤq -> ℤ_{2ᵈ} + Compress_d(x) = ⌈(2ᵈ/q)·x⌋ + ``` + + Since `⌈x⌋ = ⌊x + 1/2⌋` we have: + + ```plaintext + Compress_d(x) = ⌊(2ᵈ/q)·x + 1/2⌋ + = ⌊(2^{d+1}·x + q) / 2q⌋ + ``` + + For further information about the function implementations, consult the + `implementation_notes.pdf` document in this directory. + + The NIST FIPS 203 standard can be found at + . +*/ +static inline uint8_t +libcrux_ml_kem_vector_portable_compress_compress_message_coefficient( + uint16_t fe) { + int16_t shifted = (int16_t)1664 - (int16_t)fe; + int16_t mask = shifted >> 15U; + int16_t shifted_to_positive = mask ^ shifted; + int16_t shifted_positive_in_range = shifted_to_positive - (int16_t)832; + return (uint8_t)(shifted_positive_in_range >> 15U & (int16_t)1); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_compress_1( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + v.elements[i0] = (int16_t) + libcrux_ml_kem_vector_portable_compress_compress_message_coefficient( + (uint16_t)v.elements[i0]); + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_1_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + return libcrux_ml_kem_vector_portable_compress_compress_1(v); +} + +static KRML_MUSTINLINE uint32_t +libcrux_ml_kem_vector_portable_arithmetic_get_n_least_significant_bits( + uint8_t n, uint32_t value) { + return value & ((1U << (uint32_t)n) - 1U); +} + +static inline int16_t +libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( + uint8_t coefficient_bits, uint16_t fe) { + uint64_t compressed = (uint64_t)fe << (uint32_t)coefficient_bits; + compressed = compressed + 1664ULL; + compressed = compressed * 10321340ULL; + compressed = compressed >> 35U; + return (int16_t) + libcrux_ml_kem_vector_portable_arithmetic_get_n_least_significant_bits( + coefficient_bits, (uint32_t)compressed); +} + +static KRML_MUSTINLINE void libcrux_ml_kem_vector_portable_ntt_ntt_step( + libcrux_ml_kem_vector_portable_vector_type_PortableVector *v, int16_t zeta, + size_t i, size_t j) { + int16_t t = + libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer( + v->elements[j], zeta); + v->elements[j] = v->elements[i] - t; + v->elements[i] = v->elements[i] + t; +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_ntt_ntt_layer_1_step( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)0U, + (size_t)2U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)1U, + (size_t)3U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)4U, + (size_t)6U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)5U, + (size_t)7U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta2, (size_t)8U, + (size_t)10U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta2, (size_t)9U, + (size_t)11U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta3, (size_t)12U, + (size_t)14U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta3, (size_t)13U, + (size_t)15U); + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_ntt_layer_1_step_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_portable_ntt_ntt_layer_1_step(a, zeta0, zeta1, + zeta2, zeta3); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_ntt_ntt_layer_2_step( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta0, + int16_t zeta1) { + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)0U, + (size_t)4U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)1U, + (size_t)5U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)2U, + (size_t)6U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta0, (size_t)3U, + (size_t)7U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)8U, + (size_t)12U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)9U, + (size_t)13U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)10U, + (size_t)14U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta1, (size_t)11U, + (size_t)15U); + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_ntt_layer_2_step_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0, + int16_t zeta1) { + return libcrux_ml_kem_vector_portable_ntt_ntt_layer_2_step(a, zeta0, zeta1); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_ntt_ntt_layer_3_step( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta) { + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)0U, (size_t)8U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)1U, (size_t)9U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)2U, + (size_t)10U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)3U, + (size_t)11U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)4U, + (size_t)12U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)5U, + (size_t)13U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)6U, + (size_t)14U); + libcrux_ml_kem_vector_portable_ntt_ntt_step(&v, zeta, (size_t)7U, + (size_t)15U); + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_ntt_layer_3_step_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta) { + return libcrux_ml_kem_vector_portable_ntt_ntt_layer_3_step(a, zeta); +} + +static KRML_MUSTINLINE void libcrux_ml_kem_vector_portable_ntt_inv_ntt_step( + libcrux_ml_kem_vector_portable_vector_type_PortableVector *v, int16_t zeta, + size_t i, size_t j) { + int16_t a_minus_b = v->elements[j] - v->elements[i]; + v->elements[i] = + libcrux_ml_kem_vector_portable_arithmetic_barrett_reduce_element( + v->elements[i] + v->elements[j]); + v->elements[j] = + libcrux_ml_kem_vector_portable_arithmetic_montgomery_multiply_fe_by_fer( + a_minus_b, zeta); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_1_step( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)0U, + (size_t)2U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)1U, + (size_t)3U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)4U, + (size_t)6U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)5U, + (size_t)7U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta2, (size_t)8U, + (size_t)10U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta2, (size_t)9U, + (size_t)11U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta3, (size_t)12U, + (size_t)14U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta3, (size_t)13U, + (size_t)15U); + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_inv_ntt_layer_1_step_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0, + int16_t zeta1, int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_1_step( + a, zeta0, zeta1, zeta2, zeta3); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_2_step( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta0, + int16_t zeta1) { + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)0U, + (size_t)4U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)1U, + (size_t)5U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)2U, + (size_t)6U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta0, (size_t)3U, + (size_t)7U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)8U, + (size_t)12U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)9U, + (size_t)13U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)10U, + (size_t)14U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta1, (size_t)11U, + (size_t)15U); + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_inv_ntt_layer_2_step_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta0, + int16_t zeta1) { + return libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_2_step(a, zeta0, + zeta1); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_3_step( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t zeta) { + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)0U, + (size_t)8U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)1U, + (size_t)9U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)2U, + (size_t)10U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)3U, + (size_t)11U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)4U, + (size_t)12U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)5U, + (size_t)13U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)6U, + (size_t)14U); + libcrux_ml_kem_vector_portable_ntt_inv_ntt_step(&v, zeta, (size_t)7U, + (size_t)15U); + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_inv_ntt_layer_3_step_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, int16_t zeta) { + return libcrux_ml_kem_vector_portable_ntt_inv_ntt_layer_3_step(a, zeta); +} + +/** + Compute the product of two Kyber binomials with respect to the + modulus `X² - zeta`. + + This function almost implements Algorithm 11 of the + NIST FIPS 203 standard, which is reproduced below: + + ```plaintext + Input: a₀, a₁, b₀, b₁ ∈ ℤq. + Input: γ ∈ ℤq. + Output: c₀, c₁ ∈ ℤq. + + c₀ ← a₀·b₀ + a₁·b₁·γ + c₁ ← a₀·b₁ + a₁·b₀ + return c₀, c₁ + ``` + We say "almost" because the coefficients output by this function are in + the Montgomery domain (unlike in the specification). + + The NIST FIPS 203 standard can be found at + . +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( + libcrux_ml_kem_vector_portable_vector_type_PortableVector *a, + libcrux_ml_kem_vector_portable_vector_type_PortableVector *b, int16_t zeta, + size_t i, size_t j, + libcrux_ml_kem_vector_portable_vector_type_PortableVector *out) { + int16_t o0 = libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( + (int32_t)a->elements[i] * (int32_t)b->elements[i] + + (int32_t) + libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( + (int32_t)a->elements[j] * (int32_t)b->elements[j]) * + (int32_t)zeta); + int16_t o1 = + libcrux_ml_kem_vector_portable_arithmetic_montgomery_reduce_element( + (int32_t)a->elements[i] * (int32_t)b->elements[j] + + (int32_t)a->elements[j] * (int32_t)b->elements[i]); + out->elements[i] = o0; + out->elements[j] = o1; +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_ntt_ntt_multiply( + libcrux_ml_kem_vector_portable_vector_type_PortableVector *lhs, + libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs, + int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector out = + libcrux_ml_kem_vector_portable_vector_type_zero(); + libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( + lhs, rhs, zeta0, (size_t)0U, (size_t)1U, &out); + libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( + lhs, rhs, -zeta0, (size_t)2U, (size_t)3U, &out); + libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( + lhs, rhs, zeta1, (size_t)4U, (size_t)5U, &out); + libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( + lhs, rhs, -zeta1, (size_t)6U, (size_t)7U, &out); + libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( + lhs, rhs, zeta2, (size_t)8U, (size_t)9U, &out); + libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( + lhs, rhs, -zeta2, (size_t)10U, (size_t)11U, &out); + libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( + lhs, rhs, zeta3, (size_t)12U, (size_t)13U, &out); + libcrux_ml_kem_vector_portable_ntt_ntt_multiply_binomials( + lhs, rhs, -zeta3, (size_t)14U, (size_t)15U, &out); + return out; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_ntt_multiply_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector *lhs, + libcrux_ml_kem_vector_portable_vector_type_PortableVector *rhs, + int16_t zeta0, int16_t zeta1, int16_t zeta2, int16_t zeta3) { + return libcrux_ml_kem_vector_portable_ntt_ntt_multiply(lhs, rhs, zeta0, zeta1, + zeta2, zeta3); +} + +static KRML_MUSTINLINE void +libcrux_ml_kem_vector_portable_serialize_serialize_1( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, + uint8_t ret[2U]) { + uint8_t result[2U] = {0U}; + for (size_t i = (size_t)0U; i < (size_t)8U; i++) { + size_t i0 = i; + size_t uu____0 = (size_t)0U; + result[uu____0] = (uint32_t)result[uu____0] | + (uint32_t)(uint8_t)v.elements[i0] << (uint32_t)i0; + } + for (size_t i = (size_t)8U; i < (size_t)16U; i++) { + size_t i0 = i; + size_t uu____1 = (size_t)1U; + result[uu____1] = + (uint32_t)result[uu____1] | (uint32_t)(uint8_t)v.elements[i0] + << (uint32_t)(i0 - (size_t)8U); + } + memcpy(ret, result, (size_t)2U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline void libcrux_ml_kem_vector_portable_serialize_1_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, + uint8_t ret[2U]) { + libcrux_ml_kem_vector_portable_serialize_serialize_1(a, ret); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_serialize_deserialize_1(Eurydice_slice v) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector result = + libcrux_ml_kem_vector_portable_vector_type_zero(); + for (size_t i = (size_t)0U; i < (size_t)8U; i++) { + size_t i0 = i; + result.elements[i0] = (int16_t)((uint32_t)Eurydice_slice_index( + v, (size_t)0U, uint8_t, uint8_t *) >> + (uint32_t)i0 & + 1U); + } + for (size_t i = (size_t)8U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + result.elements[i0] = (int16_t)((uint32_t)Eurydice_slice_index( + v, (size_t)1U, uint8_t, uint8_t *) >> + (uint32_t)(i0 - (size_t)8U) & + 1U); + } + return result; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_deserialize_1_0d(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_serialize_deserialize_1(a); +} + +typedef struct uint8_t_x4_s { + uint8_t fst; + uint8_t snd; + uint8_t thd; + uint8_t f3; +} uint8_t_x4; + +static KRML_MUSTINLINE uint8_t_x4 +libcrux_ml_kem_vector_portable_serialize_serialize_4_int(Eurydice_slice v) { + uint8_t result0 = + (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) + << 4U | + (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)0U, int16_t, + int16_t *); + uint8_t result1 = + (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) + << 4U | + (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)2U, int16_t, + int16_t *); + uint8_t result2 = + (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *) + << 4U | + (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)4U, int16_t, + int16_t *); + uint8_t result3 = + (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *) + << 4U | + (uint32_t)(uint8_t)Eurydice_slice_index(v, (size_t)6U, int16_t, + int16_t *); + return (CLITERAL(uint8_t_x4){ + .fst = result0, .snd = result1, .thd = result2, .f3 = result3}); +} + +static KRML_MUSTINLINE void +libcrux_ml_kem_vector_portable_serialize_serialize_4( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, + uint8_t ret[8U]) { + uint8_t_x4 result0_3 = + libcrux_ml_kem_vector_portable_serialize_serialize_4_int( + Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)8U, + int16_t)); + uint8_t_x4 result4_7 = + libcrux_ml_kem_vector_portable_serialize_serialize_4_int( + Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)16U, + int16_t)); + uint8_t result[8U] = {0U}; + result[0U] = result0_3.fst; + result[1U] = result0_3.snd; + result[2U] = result0_3.thd; + result[3U] = result0_3.f3; + result[4U] = result4_7.fst; + result[5U] = result4_7.snd; + result[6U] = result4_7.thd; + result[7U] = result4_7.f3; + memcpy(ret, result, (size_t)8U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline void libcrux_ml_kem_vector_portable_serialize_4_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, + uint8_t ret[8U]) { + libcrux_ml_kem_vector_portable_serialize_serialize_4(a, ret); +} + +static KRML_MUSTINLINE int16_t_x8 +libcrux_ml_kem_vector_portable_serialize_deserialize_4_int( + Eurydice_slice bytes) { + int16_t v0 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)0U, + uint8_t, uint8_t *) & + 15U); + int16_t v1 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)0U, + uint8_t, uint8_t *) >> + 4U & + 15U); + int16_t v2 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, + uint8_t, uint8_t *) & + 15U); + int16_t v3 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, + uint8_t, uint8_t *) >> + 4U & + 15U); + int16_t v4 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)2U, + uint8_t, uint8_t *) & + 15U); + int16_t v5 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)2U, + uint8_t, uint8_t *) >> + 4U & + 15U); + int16_t v6 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, + uint8_t, uint8_t *) & + 15U); + int16_t v7 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, + uint8_t, uint8_t *) >> + 4U & + 15U); + return (CLITERAL(int16_t_x8){.fst = v0, + .snd = v1, + .thd = v2, + .f3 = v3, + .f4 = v4, + .f5 = v5, + .f6 = v6, + .f7 = v7}); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_serialize_deserialize_4(Eurydice_slice bytes) { + int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_4_int( + Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)4U, uint8_t)); + int16_t_x8 v8_15 = libcrux_ml_kem_vector_portable_serialize_deserialize_4_int( + Eurydice_slice_subslice2(bytes, (size_t)4U, (size_t)8U, uint8_t)); + libcrux_ml_kem_vector_portable_vector_type_PortableVector v = + libcrux_ml_kem_vector_portable_vector_type_zero(); + v.elements[0U] = v0_7.fst; + v.elements[1U] = v0_7.snd; + v.elements[2U] = v0_7.thd; + v.elements[3U] = v0_7.f3; + v.elements[4U] = v0_7.f4; + v.elements[5U] = v0_7.f5; + v.elements[6U] = v0_7.f6; + v.elements[7U] = v0_7.f7; + v.elements[8U] = v8_15.fst; + v.elements[9U] = v8_15.snd; + v.elements[10U] = v8_15.thd; + v.elements[11U] = v8_15.f3; + v.elements[12U] = v8_15.f4; + v.elements[13U] = v8_15.f5; + v.elements[14U] = v8_15.f6; + v.elements[15U] = v8_15.f7; + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_deserialize_4_0d(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_serialize_deserialize_4(a); +} + +typedef struct uint8_t_x5_s { + uint8_t fst; + uint8_t snd; + uint8_t thd; + uint8_t f3; + uint8_t f4; +} uint8_t_x5; + +static KRML_MUSTINLINE uint8_t_x5 +libcrux_ml_kem_vector_portable_serialize_serialize_5_int(Eurydice_slice v) { + uint8_t r0 = + (uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) | + Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) << 5U); + uint8_t r1 = + (uint8_t)((Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) >> 3U | + Eurydice_slice_index(v, (size_t)2U, int16_t, int16_t *) + << 2U) | + Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) << 7U); + uint8_t r2 = + (uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) >> 1U | + Eurydice_slice_index(v, (size_t)4U, int16_t, int16_t *) << 4U); + uint8_t r3 = + (uint8_t)((Eurydice_slice_index(v, (size_t)4U, int16_t, int16_t *) >> 4U | + Eurydice_slice_index(v, (size_t)5U, int16_t, int16_t *) + << 1U) | + Eurydice_slice_index(v, (size_t)6U, int16_t, int16_t *) << 6U); + uint8_t r4 = + (uint8_t)(Eurydice_slice_index(v, (size_t)6U, int16_t, int16_t *) >> 2U | + Eurydice_slice_index(v, (size_t)7U, int16_t, int16_t *) << 3U); + return (CLITERAL(uint8_t_x5){ + .fst = r0, .snd = r1, .thd = r2, .f3 = r3, .f4 = r4}); +} + +static KRML_MUSTINLINE void +libcrux_ml_kem_vector_portable_serialize_serialize_5( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, + uint8_t ret[10U]) { + uint8_t_x5 r0_4 = libcrux_ml_kem_vector_portable_serialize_serialize_5_int( + Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)8U, int16_t)); + uint8_t_x5 r5_9 = libcrux_ml_kem_vector_portable_serialize_serialize_5_int( + Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)16U, + int16_t)); + uint8_t result[10U] = {0U}; + result[0U] = r0_4.fst; + result[1U] = r0_4.snd; + result[2U] = r0_4.thd; + result[3U] = r0_4.f3; + result[4U] = r0_4.f4; + result[5U] = r5_9.fst; + result[6U] = r5_9.snd; + result[7U] = r5_9.thd; + result[8U] = r5_9.f3; + result[9U] = r5_9.f4; + memcpy(ret, result, (size_t)10U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline void libcrux_ml_kem_vector_portable_serialize_5_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, + uint8_t ret[10U]) { + libcrux_ml_kem_vector_portable_serialize_serialize_5(a, ret); +} + +static KRML_MUSTINLINE int16_t_x8 +libcrux_ml_kem_vector_portable_serialize_deserialize_5_int( + Eurydice_slice bytes) { + int16_t v0 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)0U, + uint8_t, uint8_t *) & + 31U); + int16_t v1 = (int16_t)(((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, + uint8_t, uint8_t *) & + 3U) << 3U | + (uint32_t)Eurydice_slice_index(bytes, (size_t)0U, + uint8_t, uint8_t *) >> + 5U); + int16_t v2 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)1U, + uint8_t, uint8_t *) >> + 2U & + 31U); + int16_t v3 = (int16_t)(((uint32_t)Eurydice_slice_index(bytes, (size_t)2U, + uint8_t, uint8_t *) & + 15U) + << 1U | + (uint32_t)Eurydice_slice_index(bytes, (size_t)1U, + uint8_t, uint8_t *) >> + 7U); + int16_t v4 = (int16_t)(((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, + uint8_t, uint8_t *) & + 1U) << 4U | + (uint32_t)Eurydice_slice_index(bytes, (size_t)2U, + uint8_t, uint8_t *) >> + 4U); + int16_t v5 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)3U, + uint8_t, uint8_t *) >> + 1U & + 31U); + int16_t v6 = (int16_t)(((uint32_t)Eurydice_slice_index(bytes, (size_t)4U, + uint8_t, uint8_t *) & + 7U) << 2U | + (uint32_t)Eurydice_slice_index(bytes, (size_t)3U, + uint8_t, uint8_t *) >> + 6U); + int16_t v7 = (int16_t)((uint32_t)Eurydice_slice_index(bytes, (size_t)4U, + uint8_t, uint8_t *) >> + 3U); + return (CLITERAL(int16_t_x8){.fst = v0, + .snd = v1, + .thd = v2, + .f3 = v3, + .f4 = v4, + .f5 = v5, + .f6 = v6, + .f7 = v7}); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_serialize_deserialize_5(Eurydice_slice bytes) { + int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_5_int( + Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)5U, uint8_t)); + int16_t_x8 v8_15 = libcrux_ml_kem_vector_portable_serialize_deserialize_5_int( + Eurydice_slice_subslice2(bytes, (size_t)5U, (size_t)10U, uint8_t)); + libcrux_ml_kem_vector_portable_vector_type_PortableVector v = + libcrux_ml_kem_vector_portable_vector_type_zero(); + v.elements[0U] = v0_7.fst; + v.elements[1U] = v0_7.snd; + v.elements[2U] = v0_7.thd; + v.elements[3U] = v0_7.f3; + v.elements[4U] = v0_7.f4; + v.elements[5U] = v0_7.f5; + v.elements[6U] = v0_7.f6; + v.elements[7U] = v0_7.f7; + v.elements[8U] = v8_15.fst; + v.elements[9U] = v8_15.snd; + v.elements[10U] = v8_15.thd; + v.elements[11U] = v8_15.f3; + v.elements[12U] = v8_15.f4; + v.elements[13U] = v8_15.f5; + v.elements[14U] = v8_15.f6; + v.elements[15U] = v8_15.f7; + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_deserialize_5_0d(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_serialize_deserialize_5(a); +} + +static KRML_MUSTINLINE uint8_t_x5 +libcrux_ml_kem_vector_portable_serialize_serialize_10_int(Eurydice_slice v) { + uint8_t r0 = + (uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) & + (int16_t)255); + uint8_t r1 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t, + int16_t *) & + (int16_t)63) + << 2U | + (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, + int16_t *) >> + 8U & + (int16_t)3); + uint8_t r2 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t, + int16_t *) & + (int16_t)15) + << 4U | + (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t, + int16_t *) >> + 6U & + (int16_t)15); + uint8_t r3 = (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t, + int16_t *) & + (int16_t)3) + << 6U | + (uint32_t)(uint8_t)(Eurydice_slice_index(v, (size_t)2U, int16_t, + int16_t *) >> + 4U & + (int16_t)63); + uint8_t r4 = + (uint8_t)(Eurydice_slice_index(v, (size_t)3U, int16_t, int16_t *) >> 2U & + (int16_t)255); + return (CLITERAL(uint8_t_x5){ + .fst = r0, .snd = r1, .thd = r2, .f3 = r3, .f4 = r4}); +} + +static KRML_MUSTINLINE void +libcrux_ml_kem_vector_portable_serialize_serialize_10( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, + uint8_t ret[20U]) { + uint8_t_x5 r0_4 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int( + Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)4U, int16_t)); + uint8_t_x5 r5_9 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int( + Eurydice_array_to_subslice2(v.elements, (size_t)4U, (size_t)8U, int16_t)); + uint8_t_x5 r10_14 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int( + Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)12U, + int16_t)); + uint8_t_x5 r15_19 = libcrux_ml_kem_vector_portable_serialize_serialize_10_int( + Eurydice_array_to_subslice2(v.elements, (size_t)12U, (size_t)16U, + int16_t)); + uint8_t result[20U] = {0U}; + result[0U] = r0_4.fst; + result[1U] = r0_4.snd; + result[2U] = r0_4.thd; + result[3U] = r0_4.f3; + result[4U] = r0_4.f4; + result[5U] = r5_9.fst; + result[6U] = r5_9.snd; + result[7U] = r5_9.thd; + result[8U] = r5_9.f3; + result[9U] = r5_9.f4; + result[10U] = r10_14.fst; + result[11U] = r10_14.snd; + result[12U] = r10_14.thd; + result[13U] = r10_14.f3; + result[14U] = r10_14.f4; + result[15U] = r15_19.fst; + result[16U] = r15_19.snd; + result[17U] = r15_19.thd; + result[18U] = r15_19.f3; + result[19U] = r15_19.f4; + memcpy(ret, result, (size_t)20U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline void libcrux_ml_kem_vector_portable_serialize_10_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, + uint8_t ret[20U]) { + libcrux_ml_kem_vector_portable_serialize_serialize_10(a, ret); +} + +static KRML_MUSTINLINE int16_t_x8 +libcrux_ml_kem_vector_portable_serialize_deserialize_10_int( + Eurydice_slice bytes) { + int16_t r0 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) & + (int16_t)3) + << 8U | + ((int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *) & + (int16_t)255); + int16_t r1 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) & + (int16_t)15) + << 6U | + (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *) >> + 2U; + int16_t r2 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) & + (int16_t)63) + << 4U | + (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *) >> + 4U; + int16_t r3 = + (int16_t)Eurydice_slice_index(bytes, (size_t)4U, uint8_t, uint8_t *) + << 2U | + (int16_t)Eurydice_slice_index(bytes, (size_t)3U, uint8_t, uint8_t *) >> + 6U; + int16_t r4 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *) & + (int16_t)3) + << 8U | + ((int16_t)Eurydice_slice_index(bytes, (size_t)5U, uint8_t, uint8_t *) & + (int16_t)255); + int16_t r5 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *) & + (int16_t)15) + << 6U | + (int16_t)Eurydice_slice_index(bytes, (size_t)6U, uint8_t, uint8_t *) >> + 2U; + int16_t r6 = + ((int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *) & + (int16_t)63) + << 4U | + (int16_t)Eurydice_slice_index(bytes, (size_t)7U, uint8_t, uint8_t *) >> + 4U; + int16_t r7 = + (int16_t)Eurydice_slice_index(bytes, (size_t)9U, uint8_t, uint8_t *) + << 2U | + (int16_t)Eurydice_slice_index(bytes, (size_t)8U, uint8_t, uint8_t *) >> + 6U; + return (CLITERAL(int16_t_x8){.fst = r0, + .snd = r1, + .thd = r2, + .f3 = r3, + .f4 = r4, + .f5 = r5, + .f6 = r6, + .f7 = r7}); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_serialize_deserialize_10(Eurydice_slice bytes) { + int16_t_x8 v0_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_10_int( + Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)10U, uint8_t)); + int16_t_x8 v8_15 = + libcrux_ml_kem_vector_portable_serialize_deserialize_10_int( + Eurydice_slice_subslice2(bytes, (size_t)10U, (size_t)20U, uint8_t)); + libcrux_ml_kem_vector_portable_vector_type_PortableVector v = + libcrux_ml_kem_vector_portable_vector_type_zero(); + v.elements[0U] = v0_7.fst; + v.elements[1U] = v0_7.snd; + v.elements[2U] = v0_7.thd; + v.elements[3U] = v0_7.f3; + v.elements[4U] = v0_7.f4; + v.elements[5U] = v0_7.f5; + v.elements[6U] = v0_7.f6; + v.elements[7U] = v0_7.f7; + v.elements[8U] = v8_15.fst; + v.elements[9U] = v8_15.snd; + v.elements[10U] = v8_15.thd; + v.elements[11U] = v8_15.f3; + v.elements[12U] = v8_15.f4; + v.elements[13U] = v8_15.f5; + v.elements[14U] = v8_15.f6; + v.elements[15U] = v8_15.f7; + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_deserialize_10_0d(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_serialize_deserialize_10(a); +} + +typedef struct uint8_t_x3_s { + uint8_t fst; + uint8_t snd; + uint8_t thd; +} uint8_t_x3; + +static KRML_MUSTINLINE uint8_t_x3 +libcrux_ml_kem_vector_portable_serialize_serialize_12_int(Eurydice_slice v) { + uint8_t r0 = + (uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) & + (int16_t)255); + uint8_t r1 = + (uint8_t)(Eurydice_slice_index(v, (size_t)0U, int16_t, int16_t *) >> 8U | + (Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) & + (int16_t)15) + << 4U); + uint8_t r2 = + (uint8_t)(Eurydice_slice_index(v, (size_t)1U, int16_t, int16_t *) >> 4U & + (int16_t)255); + return (CLITERAL(uint8_t_x3){.fst = r0, .snd = r1, .thd = r2}); +} + +static KRML_MUSTINLINE void +libcrux_ml_kem_vector_portable_serialize_serialize_12( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, + uint8_t ret[24U]) { + uint8_t_x3 r0_2 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( + Eurydice_array_to_subslice2(v.elements, (size_t)0U, (size_t)2U, int16_t)); + uint8_t_x3 r3_5 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( + Eurydice_array_to_subslice2(v.elements, (size_t)2U, (size_t)4U, int16_t)); + uint8_t_x3 r6_8 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( + Eurydice_array_to_subslice2(v.elements, (size_t)4U, (size_t)6U, int16_t)); + uint8_t_x3 r9_11 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( + Eurydice_array_to_subslice2(v.elements, (size_t)6U, (size_t)8U, int16_t)); + uint8_t_x3 r12_14 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( + Eurydice_array_to_subslice2(v.elements, (size_t)8U, (size_t)10U, + int16_t)); + uint8_t_x3 r15_17 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( + Eurydice_array_to_subslice2(v.elements, (size_t)10U, (size_t)12U, + int16_t)); + uint8_t_x3 r18_20 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( + Eurydice_array_to_subslice2(v.elements, (size_t)12U, (size_t)14U, + int16_t)); + uint8_t_x3 r21_23 = libcrux_ml_kem_vector_portable_serialize_serialize_12_int( + Eurydice_array_to_subslice2(v.elements, (size_t)14U, (size_t)16U, + int16_t)); + uint8_t result[24U] = {0U}; + result[0U] = r0_2.fst; + result[1U] = r0_2.snd; + result[2U] = r0_2.thd; + result[3U] = r3_5.fst; + result[4U] = r3_5.snd; + result[5U] = r3_5.thd; + result[6U] = r6_8.fst; + result[7U] = r6_8.snd; + result[8U] = r6_8.thd; + result[9U] = r9_11.fst; + result[10U] = r9_11.snd; + result[11U] = r9_11.thd; + result[12U] = r12_14.fst; + result[13U] = r12_14.snd; + result[14U] = r12_14.thd; + result[15U] = r15_17.fst; + result[16U] = r15_17.snd; + result[17U] = r15_17.thd; + result[18U] = r18_20.fst; + result[19U] = r18_20.snd; + result[20U] = r18_20.thd; + result[21U] = r21_23.fst; + result[22U] = r21_23.snd; + result[23U] = r21_23.thd; + memcpy(ret, result, (size_t)24U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline void libcrux_ml_kem_vector_portable_serialize_12_0d( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, + uint8_t ret[24U]) { + libcrux_ml_kem_vector_portable_serialize_serialize_12(a, ret); +} + +typedef struct int16_t_x2_s { + int16_t fst; + int16_t snd; +} int16_t_x2; + +static KRML_MUSTINLINE int16_t_x2 +libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( + Eurydice_slice bytes) { + int16_t byte0 = + (int16_t)Eurydice_slice_index(bytes, (size_t)0U, uint8_t, uint8_t *); + int16_t byte1 = + (int16_t)Eurydice_slice_index(bytes, (size_t)1U, uint8_t, uint8_t *); + int16_t byte2 = + (int16_t)Eurydice_slice_index(bytes, (size_t)2U, uint8_t, uint8_t *); + int16_t r0 = (byte1 & (int16_t)15) << 8U | (byte0 & (int16_t)255); + int16_t r1 = byte2 << 4U | (byte1 >> 4U & (int16_t)15); + return (CLITERAL(int16_t_x2){.fst = r0, .snd = r1}); +} + +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_serialize_deserialize_12(Eurydice_slice bytes) { + int16_t_x2 v0_1 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( + Eurydice_slice_subslice2(bytes, (size_t)0U, (size_t)3U, uint8_t)); + int16_t_x2 v2_3 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( + Eurydice_slice_subslice2(bytes, (size_t)3U, (size_t)6U, uint8_t)); + int16_t_x2 v4_5 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( + Eurydice_slice_subslice2(bytes, (size_t)6U, (size_t)9U, uint8_t)); + int16_t_x2 v6_7 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( + Eurydice_slice_subslice2(bytes, (size_t)9U, (size_t)12U, uint8_t)); + int16_t_x2 v8_9 = libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( + Eurydice_slice_subslice2(bytes, (size_t)12U, (size_t)15U, uint8_t)); + int16_t_x2 v10_11 = + libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( + Eurydice_slice_subslice2(bytes, (size_t)15U, (size_t)18U, uint8_t)); + int16_t_x2 v12_13 = + libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( + Eurydice_slice_subslice2(bytes, (size_t)18U, (size_t)21U, uint8_t)); + int16_t_x2 v14_15 = + libcrux_ml_kem_vector_portable_serialize_deserialize_12_int( + Eurydice_slice_subslice2(bytes, (size_t)21U, (size_t)24U, uint8_t)); + libcrux_ml_kem_vector_portable_vector_type_PortableVector re = + libcrux_ml_kem_vector_portable_vector_type_zero(); + re.elements[0U] = v0_1.fst; + re.elements[1U] = v0_1.snd; + re.elements[2U] = v2_3.fst; + re.elements[3U] = v2_3.snd; + re.elements[4U] = v4_5.fst; + re.elements[5U] = v4_5.snd; + re.elements[6U] = v6_7.fst; + re.elements[7U] = v6_7.snd; + re.elements[8U] = v8_9.fst; + re.elements[9U] = v8_9.snd; + re.elements[10U] = v10_11.fst; + re.elements[11U] = v10_11.snd; + re.elements[12U] = v12_13.fst; + re.elements[13U] = v12_13.snd; + re.elements[14U] = v14_15.fst; + re.elements[15U] = v14_15.snd; + return re; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_deserialize_12_0d(Eurydice_slice a) { + return libcrux_ml_kem_vector_portable_serialize_deserialize_12(a); +} + +static KRML_MUSTINLINE size_t +libcrux_ml_kem_vector_portable_sampling_rej_sample(Eurydice_slice a, + Eurydice_slice result) { + size_t sampled = (size_t)0U; + for (size_t i = (size_t)0U; i < Eurydice_slice_len(a, uint8_t) / (size_t)3U; + i++) { + size_t i0 = i; + int16_t b1 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)0U, + uint8_t, uint8_t *); + int16_t b2 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)1U, + uint8_t, uint8_t *); + int16_t b3 = (int16_t)Eurydice_slice_index(a, i0 * (size_t)3U + (size_t)2U, + uint8_t, uint8_t *); + int16_t d1 = (b2 & (int16_t)15) << 8U | b1; + int16_t d2 = b3 << 4U | b2 >> 4U; + bool uu____0; + int16_t uu____1; + bool uu____2; + size_t uu____3; + int16_t uu____4; + size_t uu____5; + int16_t uu____6; + if (d1 < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS) { + if (sampled < (size_t)16U) { + Eurydice_slice_index(result, sampled, int16_t, int16_t *) = d1; + sampled++; + uu____1 = d2; + uu____6 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + uu____0 = uu____1 < uu____6; + if (uu____0) { + uu____3 = sampled; + uu____2 = uu____3 < (size_t)16U; + if (uu____2) { + uu____4 = d2; + uu____5 = sampled; + Eurydice_slice_index(result, uu____5, int16_t, int16_t *) = uu____4; + sampled++; + continue; + } + } + continue; + } + } + uu____1 = d2; + uu____6 = LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + uu____0 = uu____1 < uu____6; + if (uu____0) { + uu____3 = sampled; + uu____2 = uu____3 < (size_t)16U; + if (uu____2) { + uu____4 = d2; + uu____5 = sampled; + Eurydice_slice_index(result, uu____5, int16_t, int16_t *) = uu____4; + sampled++; + continue; + } + } + } + return sampled; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline size_t libcrux_ml_kem_vector_portable_rej_sample_0d( + Eurydice_slice a, Eurydice_slice out) { + return libcrux_ml_kem_vector_portable_sampling_rej_sample(a, out); +} + +#define LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 ((size_t)10U) + +#define LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_MLKEM768_VECTOR_U_COMPRESSION_FACTOR_768 / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_RANK_768 ((size_t)3U) + +#define LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_C1_BLOCK_SIZE_768 * LIBCRUX_ML_KEM_MLKEM768_RANK_768) + +#define LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR_768 ((size_t)4U) + +#define LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768 \ + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_MLKEM768_VECTOR_V_COMPRESSION_FACTOR_768 / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_C1_SIZE_768 + LIBCRUX_ML_KEM_MLKEM768_C2_SIZE_768) + +#define LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_T_AS_NTT_ENCODED_SIZE_768 + (size_t)32U) + +#define LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_COEFFICIENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_ETA1 ((size_t)2U) + +#define LIBCRUX_ML_KEM_MLKEM768_ETA1_RANDOMNESS_SIZE \ + (LIBCRUX_ML_KEM_MLKEM768_ETA1 * (size_t)64U) + +#define LIBCRUX_ML_KEM_MLKEM768_ETA2 ((size_t)2U) + +#define LIBCRUX_ML_KEM_MLKEM768_ETA2_RANDOMNESS_SIZE \ + (LIBCRUX_ML_KEM_MLKEM768_ETA2 * (size_t)64U) + +#define LIBCRUX_ML_KEM_MLKEM768_IMPLICIT_REJECTION_HASH_INPUT_SIZE \ + (LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE + \ + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_CIPHERTEXT_SIZE_768) + +typedef libcrux_ml_kem_types_MlKemPrivateKey_55 + libcrux_ml_kem_mlkem768_MlKem768PrivateKey; + +typedef libcrux_ml_kem_types_MlKemPublicKey_15 + libcrux_ml_kem_mlkem768_MlKem768PublicKey; + +#define LIBCRUX_ML_KEM_MLKEM768_RANKED_BYTES_PER_RING_ELEMENT_768 \ + (LIBCRUX_ML_KEM_MLKEM768_RANK_768 * \ + LIBCRUX_ML_KEM_CONSTANTS_BITS_PER_RING_ELEMENT / (size_t)8U) + +#define LIBCRUX_ML_KEM_MLKEM768_SECRET_KEY_SIZE_768 \ + (LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_SECRET_KEY_SIZE_768 + \ + LIBCRUX_ML_KEM_MLKEM768_CPA_PKE_PUBLIC_KEY_SIZE_768 + \ + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE + \ + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE) + +/** +A monomorphic instance of libcrux_ml_kem.polynomial.PolynomialRingElement +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector + +*/ +typedef struct libcrux_ml_kem_polynomial_PolynomialRingElement_f0_s { + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficients[16U]; +} libcrux_ml_kem_polynomial_PolynomialRingElement_f0; + +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.ZERO_89 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_polynomial_ZERO_89_ea(void) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 lit; + lit.coefficients[0U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[1U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[2U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[3U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[4U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[5U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[6U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[7U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[8U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[9U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[10U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[11U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[12U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[13U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[14U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + lit.coefficients[15U] = libcrux_ml_kem_vector_portable_ZERO_0d(); + return lit; +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_secret_key.closure +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_ind_cpa_deserialize_secret_key_closure_6b(size_t _) { + return libcrux_ml_kem_polynomial_ZERO_89_ea(); +} + +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_to_uncompressed_ring_element with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element_af( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = + libcrux_ml_kem_polynomial_ZERO_89_ea(); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(serialized, uint8_t) / (size_t)24U; i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice2( + serialized, i0 * (size_t)24U, i0 * (size_t)24U + (size_t)24U, uint8_t); + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_deserialize_12_0d(bytes); + re.coefficients[i0] = uu____0; + } + return re; +} + +/** + Call [`deserialize_to_uncompressed_ring_element`] for each ring element. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_secret_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_deserialize_secret_key_24( + Eurydice_slice secret_key, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + secret_as_ntt[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); + } + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(secret_key, uint8_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice secret_bytes = Eurydice_slice_subslice2( + secret_key, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + uint8_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____0 = + libcrux_ml_kem_serialize_deserialize_to_uncompressed_ring_element_af( + secret_bytes); + secret_as_ntt[i0] = uu____0; + } + memcpy( + ret, secret_as_ntt, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); +} + +/** +A monomorphic instance of +libcrux_ml_kem.ind_cpa.unpacked.IndCpaPrivateKeyUnpacked with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- $3size_t +*/ +typedef struct libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_f8_s { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U]; +} libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_f8; + +/** +A monomorphic instance of +libcrux_ml_kem.ind_cpa.deserialize_then_decompress_u.closure with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 +- CIPHERTEXT_SIZE= 1088 +- U_COMPRESSION_FACTOR= 10 +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_closure_7c(size_t _) { + return libcrux_ml_kem_polynomial_ZERO_89_ea(); +} + +/** +A monomorphic instance of +libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with +const generics +- COEFFICIENT_BITS= 10 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int32_t decompressed = (int32_t)v.elements[i0] * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)10); + decompressed = decompressed >> (uint32_t)((int32_t)10 + (int32_t)1); + v.elements[i0] = (int16_t)decompressed; + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_0d with const +generics +- COEFFICIENT_BITS= 10 +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b( + v); +} + +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_then_decompress_10 with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_serialize_deserialize_then_decompress_10_2c( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = + libcrux_ml_kem_polynomial_ZERO_89_ea(); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(serialized, uint8_t) / (size_t)20U; i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice2( + serialized, i0 * (size_t)20U, i0 * (size_t)20U + (size_t)20U, uint8_t); + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = + libcrux_ml_kem_vector_portable_deserialize_10_0d(bytes); + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +/** +A monomorphic instance of +libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with +const generics +- COEFFICIENT_BITS= 11 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b0( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int32_t decompressed = (int32_t)v.elements[i0] * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)11); + decompressed = decompressed >> (uint32_t)((int32_t)11 + (int32_t)1); + v.elements[i0] = (int16_t)decompressed; + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_0d with const +generics +- COEFFICIENT_BITS= 11 +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a0( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b0( + v); +} + +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_then_decompress_11 with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_serialize_deserialize_then_decompress_11_8d( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = + libcrux_ml_kem_polynomial_ZERO_89_ea(); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(serialized, uint8_t) / (size_t)22U; i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice2( + serialized, i0 * (size_t)22U, i0 * (size_t)22U + (size_t)22U, uint8_t); + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = + libcrux_ml_kem_vector_portable_deserialize_11_0d(bytes); + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a0( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_u with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- COMPRESSION_FACTOR= 10 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u_34( + Eurydice_slice serialized) { + return libcrux_ml_kem_serialize_deserialize_then_decompress_10_2c(serialized); +} + +typedef struct libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2_s { + libcrux_ml_kem_vector_portable_vector_type_PortableVector fst; + libcrux_ml_kem_vector_portable_vector_type_PortableVector snd; +} libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2; + +/** +A monomorphic instance of libcrux_ml_kem.vector.traits.montgomery_multiply_fe +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_traits_montgomery_multiply_fe_67( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v, int16_t fer) { + return libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d(v, + fer); +} + +/** +A monomorphic instance of libcrux_ml_kem.ntt.ntt_layer_int_vec_step +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE + libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 + libcrux_ml_kem_ntt_ntt_layer_int_vec_step_0c( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, + libcrux_ml_kem_vector_portable_vector_type_PortableVector b, + int16_t zeta_r) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector t = + libcrux_ml_kem_vector_traits_montgomery_multiply_fe_67(b, zeta_r); + b = libcrux_ml_kem_vector_portable_sub_0d(a, &t); + a = libcrux_ml_kem_vector_portable_add_0d(a, &t); + return ( + CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2){ + .fst = a, .snd = b}); +} + +/** +A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_4_plus +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, + size_t layer, size_t _initial_coefficient_bound) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = offset / (size_t)16U; + size_t step_vec = step / (size_t)16U; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 uu____0 = + libcrux_ml_kem_ntt_ntt_layer_int_vec_step_0c( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + libcrux_ml_kem_vector_portable_vector_type_PortableVector x = uu____0.fst; + libcrux_ml_kem_vector_portable_vector_type_PortableVector y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +/** +A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_3 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_3_fd( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, + size_t _layer, size_t _initial_coefficient_bound) { + for (size_t i = (size_t)0U; i < (size_t)16U; i++) { + size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_ntt_layer_3_step_0d( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0; + } +} + +/** +A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_2 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_2_ad( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, + size_t _layer, size_t _initial_coefficient_bound) { + for (size_t i = (size_t)0U; i < (size_t)16U; i++) { + size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + re->coefficients[round] = + libcrux_ml_kem_vector_portable_ntt_layer_2_step_0d( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U]); + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + } +} + +/** +A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_1 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_1_a2( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, + size_t _layer, size_t _initial_coefficient_bound) { + for (size_t i = (size_t)0U; i < (size_t)16U; i++) { + size_t round = i; + zeta_i[0U] = zeta_i[0U] + (size_t)1U; + re->coefficients[round] = + libcrux_ml_kem_vector_portable_ntt_layer_1_step_0d( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] + + (size_t)3U]); + zeta_i[0U] = zeta_i[0U] + (size_t)3U; + } +} + +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.poly_barrett_reduce_89 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_poly_barrett_reduce_89_8b( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_barrett_reduce_0d( + self->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +/** +A monomorphic instance of libcrux_ml_kem.ntt.ntt_vector_u +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- VECTOR_U_COMPRESSION_FACTOR= 10 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_vector_u_9f( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re) { + size_t zeta_i = (size_t)0U; + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)7U, + (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)6U, + (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)5U, + (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)4U, + (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_3_fd(&zeta_i, re, (size_t)3U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_2_ad(&zeta_i, re, (size_t)2U, (size_t)3328U); + libcrux_ml_kem_ntt_ntt_at_layer_1_a2(&zeta_i, re, (size_t)1U, (size_t)3328U); + libcrux_ml_kem_polynomial_poly_barrett_reduce_89_8b(re); +} + +/** + Call [`deserialize_then_decompress_ring_element_u`] on each ring element + in the `ciphertext`. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.deserialize_then_decompress_u +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- CIPHERTEXT_SIZE= 1088 +- U_COMPRESSION_FACTOR= 10 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_f4( + uint8_t *ciphertext, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u_as_ntt[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + u_as_ntt[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); + } + for (size_t i = (size_t)0U; + i < Eurydice_slice_len( + Eurydice_array_to_slice((size_t)1088U, ciphertext, uint8_t), + uint8_t) / + (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U); + i++) { + size_t i0 = i; + Eurydice_slice u_bytes = Eurydice_array_to_subslice2( + ciphertext, + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U), + i0 * (LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U) + + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT * + (size_t)10U / (size_t)8U, + uint8_t); + u_as_ntt[i0] = + libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_u_34( + u_bytes); + libcrux_ml_kem_ntt_ntt_vector_u_9f(&u_as_ntt[i0]); + } + memcpy( + ret, u_as_ntt, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); +} + +/** +A monomorphic instance of +libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with +const generics +- COEFFICIENT_BITS= 4 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b1( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int32_t decompressed = (int32_t)v.elements[i0] * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)4); + decompressed = decompressed >> (uint32_t)((int32_t)4 + (int32_t)1); + v.elements[i0] = (int16_t)decompressed; + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_0d with const +generics +- COEFFICIENT_BITS= 4 +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a1( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b1( + v); +} + +/** +A monomorphic instance of libcrux_ml_kem.serialize.deserialize_then_decompress_4 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_serialize_deserialize_then_decompress_4_41( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = + libcrux_ml_kem_polynomial_ZERO_89_ea(); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(serialized, uint8_t) / (size_t)8U; i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice2( + serialized, i0 * (size_t)8U, i0 * (size_t)8U + (size_t)8U, uint8_t); + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = + libcrux_ml_kem_vector_portable_deserialize_4_0d(bytes); + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a1( + coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +/** +A monomorphic instance of +libcrux_ml_kem.vector.portable.compress.decompress_ciphertext_coefficient with +const generics +- COEFFICIENT_BITS= 5 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b2( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int32_t decompressed = (int32_t)v.elements[i0] * + (int32_t)LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS; + decompressed = (decompressed << 1U) + ((int32_t)1 << (uint32_t)(int32_t)5); + decompressed = decompressed >> (uint32_t)((int32_t)5 + (int32_t)1); + v.elements[i0] = (int16_t)decompressed; + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.vector.portable.decompress_ciphertext_coefficient_0d with const +generics +- COEFFICIENT_BITS= 5 +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a2( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + return libcrux_ml_kem_vector_portable_compress_decompress_ciphertext_coefficient_6b2( + v); +} + +/** +A monomorphic instance of libcrux_ml_kem.serialize.deserialize_then_decompress_5 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_serialize_deserialize_then_decompress_5_4e( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = + libcrux_ml_kem_polynomial_ZERO_89_ea(); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(serialized, uint8_t) / (size_t)10U; i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice2( + serialized, i0 * (size_t)10U, i0 * (size_t)10U + (size_t)10U, uint8_t); + re.coefficients[i0] = + libcrux_ml_kem_vector_portable_deserialize_5_0d(bytes); + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____1 = + libcrux_ml_kem_vector_portable_decompress_ciphertext_coefficient_0d_5a2( + re.coefficients[i0]); + re.coefficients[i0] = uu____1; + } + return re; +} + +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_then_decompress_ring_element_v with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- COMPRESSION_FACTOR= 4 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_56( + Eurydice_slice serialized) { + return libcrux_ml_kem_serialize_deserialize_then_decompress_4_41(serialized); +} + +/** + Given two `KyberPolynomialRingElement`s in their NTT representations, + compute their product. Given two polynomials in the NTT domain `f^` and `ĵ`, + the `iᵗʰ` coefficient of the product `k̂` is determined by the calculation: + + ```plaintext + ĥ[2·i] + ĥ[2·i + 1]X = (f^[2·i] + f^[2·i + 1]X)·(ĝ[2·i] + ĝ[2·i + 1]X) mod (X² + - ζ^(2·BitRev₇(i) + 1)) + ``` + + This function almost implements Algorithm 10 of the + NIST FIPS 203 standard, which is reproduced below: + + ```plaintext + Input: Two arrays fˆ ∈ ℤ₂₅₆ and ĝ ∈ ℤ₂₅₆. + Output: An array ĥ ∈ ℤq. + + for(i ← 0; i < 128; i++) + (ĥ[2i], ĥ[2i+1]) ← BaseCaseMultiply(fˆ[2i], fˆ[2i+1], ĝ[2i], ĝ[2i+1], + ζ^(2·BitRev₇(i) + 1)) end for return ĥ + ``` + We say "almost" because the coefficients of the ring element output by + this function are in the Montgomery domain. + + The NIST FIPS 203 standard can be found at + . +*/ +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.ntt_multiply_89 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_polynomial_ntt_multiply_89_2a( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *rhs) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 out = + libcrux_ml_kem_polynomial_ZERO_89_ea(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_ntt_multiply_0d( + &self->coefficients[i0], &rhs->coefficients[i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[(size_t)64U + + (size_t)4U * i0 + + (size_t)3U]); + out.coefficients[i0] = uu____0; + } + return out; +} + +/** + Given two polynomial ring elements `lhs` and `rhs`, compute the pointwise + sum of their constituent coefficients. +*/ +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.add_to_ring_element_89 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_add_to_ring_element_89_84( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *rhs) { + for (size_t i = (size_t)0U; + i < Eurydice_slice_len( + Eurydice_array_to_slice( + (size_t)16U, self->coefficients, + libcrux_ml_kem_vector_portable_vector_type_PortableVector), + libcrux_ml_kem_vector_portable_vector_type_PortableVector); + i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_add_0d(self->coefficients[i0], + &rhs->coefficients[i0]); + self->coefficients[i0] = uu____0; + } +} + +/** +A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_at_layer_1 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1_83( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, + size_t _layer) { + for (size_t i = (size_t)0U; i < (size_t)16U; i++) { + size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + re->coefficients[round] = + libcrux_ml_kem_vector_portable_inv_ntt_layer_1_step_0d( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)2U], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)3U]); + zeta_i[0U] = zeta_i[0U] - (size_t)3U; + } +} + +/** +A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_at_layer_2 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2_c3( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, + size_t _layer) { + for (size_t i = (size_t)0U; i < (size_t)16U; i++) { + size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + re->coefficients[round] = + libcrux_ml_kem_vector_portable_inv_ntt_layer_2_step_0d( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U] - + (size_t)1U]); + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + } +} + +/** +A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_at_layer_3 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3_68( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, + size_t _layer) { + for (size_t i = (size_t)0U; i < (size_t)16U; i++) { + size_t round = i; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_inv_ntt_layer_3_step_0d( + re->coefficients[round], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + re->coefficients[round] = uu____0; + } +} + +/** +A monomorphic instance of +libcrux_ml_kem.invert_ntt.inv_ntt_layer_int_vec_step_reduce with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics + +*/ +static KRML_MUSTINLINE + libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 + libcrux_ml_kem_invert_ntt_inv_ntt_layer_int_vec_step_reduce_65( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a, + libcrux_ml_kem_vector_portable_vector_type_PortableVector b, + int16_t zeta_r) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector a_minus_b = + libcrux_ml_kem_vector_portable_sub_0d(b, &a); + a = libcrux_ml_kem_vector_portable_barrett_reduce_0d( + libcrux_ml_kem_vector_portable_add_0d(a, &b)); + b = libcrux_ml_kem_vector_traits_montgomery_multiply_fe_67(a_minus_b, zeta_r); + return ( + CLITERAL(libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2){ + .fst = a, .snd = b}); +} + +/** +A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_at_layer_4_plus +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e( + size_t *zeta_i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, + size_t layer) { + size_t step = (size_t)1U << (uint32_t)layer; + for (size_t i0 = (size_t)0U; i0 < (size_t)128U >> (uint32_t)layer; i0++) { + size_t round = i0; + zeta_i[0U] = zeta_i[0U] - (size_t)1U; + size_t offset = round * step * (size_t)2U; + size_t offset_vec = + offset / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + size_t step_vec = + step / LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; + for (size_t i = offset_vec; i < offset_vec + step_vec; i++) { + size_t j = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector_x2 uu____0 = + libcrux_ml_kem_invert_ntt_inv_ntt_layer_int_vec_step_reduce_65( + re->coefficients[j], re->coefficients[j + step_vec], + libcrux_ml_kem_polynomial_ZETAS_TIMES_MONTGOMERY_R[zeta_i[0U]]); + libcrux_ml_kem_vector_portable_vector_type_PortableVector x = uu____0.fst; + libcrux_ml_kem_vector_portable_vector_type_PortableVector y = uu____0.snd; + re->coefficients[j] = x; + re->coefficients[j + step_vec] = y; + } + } +} + +/** +A monomorphic instance of libcrux_ml_kem.invert_ntt.invert_ntt_montgomery +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_f6( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re) { + size_t zeta_i = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT / (size_t)2U; + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_1_83(&zeta_i, re, (size_t)1U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_2_c3(&zeta_i, re, (size_t)2U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_3_68(&zeta_i, re, (size_t)3U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e(&zeta_i, re, + (size_t)4U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e(&zeta_i, re, + (size_t)5U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e(&zeta_i, re, + (size_t)6U); + libcrux_ml_kem_invert_ntt_invert_ntt_at_layer_4_plus_6e(&zeta_i, re, + (size_t)7U); + libcrux_ml_kem_polynomial_poly_barrett_reduce_89_8b(re); +} + +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.subtract_reduce_89 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_polynomial_subtract_reduce_89_d4( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 b) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector + coefficient_normal_form = + libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d( + b.coefficients[i0], (int16_t)1441); + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_barrett_reduce_0d( + libcrux_ml_kem_vector_portable_sub_0d(self->coefficients[i0], + &coefficient_normal_form)); + b.coefficients[i0] = uu____0; + } + return b; +} + +/** + The following functions compute various expressions involving + vectors and matrices. The computation of these expressions has been + abstracted away into these functions in order to save on loop iterations. + Compute v − InverseNTT(sᵀ ◦ NTT(u)) +*/ +/** +A monomorphic instance of libcrux_ml_kem.matrix.compute_message +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_matrix_compute_message_b3( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *v, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *secret_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *u_as_ntt) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result = + libcrux_ml_kem_polynomial_ZERO_89_ea(); + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product = + libcrux_ml_kem_polynomial_ntt_multiply_89_2a(&secret_as_ntt[i0], + &u_as_ntt[i0]); + libcrux_ml_kem_polynomial_add_to_ring_element_89_84(&result, &product); + } + libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_f6(&result); + result = libcrux_ml_kem_polynomial_subtract_reduce_89_d4(v, result); + return result; +} + +/** +A monomorphic instance of libcrux_ml_kem.vector.portable.arithmetic.shift_right +with const generics +- SHIFT_BY= 15 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_arithmetic_shift_right_94( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + v.elements[i0] = v.elements[i0] >> (uint32_t)(int32_t)15; + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +/** +A monomorphic instance of libcrux_ml_kem.vector.portable.shift_right_0d +with const generics +- SHIFT_BY= 15 +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_shift_right_0d_19( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + return libcrux_ml_kem_vector_portable_arithmetic_shift_right_94(v); +} + +/** +A monomorphic instance of +libcrux_ml_kem.vector.traits.to_unsigned_representative with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics + +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_traits_to_unsigned_representative_db( + libcrux_ml_kem_vector_portable_vector_type_PortableVector a) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector t = + libcrux_ml_kem_vector_portable_shift_right_0d_19(a); + libcrux_ml_kem_vector_portable_vector_type_PortableVector fm = + libcrux_ml_kem_vector_portable_bitwise_and_with_constant_0d( + t, LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_MODULUS); + return libcrux_ml_kem_vector_portable_add_0d(a, &fm); +} + +/** +A monomorphic instance of +libcrux_ml_kem.serialize.compress_then_serialize_message with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics + +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_serialize_compress_then_serialize_message_aa( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re, uint8_t ret[32U]) { + uint8_t serialized[32U] = {0U}; + for (size_t i = (size_t)0U; i < (size_t)16U; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = + libcrux_ml_kem_vector_traits_to_unsigned_representative_db( + re.coefficients[i0]); + libcrux_ml_kem_vector_portable_vector_type_PortableVector + coefficient_compressed = + libcrux_ml_kem_vector_portable_compress_1_0d(coefficient); + uint8_t bytes[2U]; + libcrux_ml_kem_vector_portable_serialize_1_0d(coefficient_compressed, + bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice2( + serialized, (size_t)2U * i0, (size_t)2U * i0 + (size_t)2U, uint8_t); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)2U, bytes, uint8_t), uint8_t); + } + memcpy(ret, serialized, (size_t)32U * sizeof(uint8_t)); +} + +/** + This function implements Algorithm 14 of the + NIST FIPS 203 specification; this is the Kyber CPA-PKE decryption algorithm. + + Algorithm 14 is reproduced below: + + ```plaintext + Input: decryption key dkₚₖₑ ∈ 𝔹^{384k}. + Input: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. + Output: message m ∈ 𝔹^{32}. + + c₁ ← c[0 : 32dᵤk] + c₂ ← c[32dᵤk : 32(dᵤk + dᵥ)] + u ← Decompress_{dᵤ}(ByteDecode_{dᵤ}(c₁)) + v ← Decompress_{dᵥ}(ByteDecode_{dᵥ}(c₂)) + ŝ ← ByteDecode₁₂(dkₚₖₑ) + w ← v - NTT-¹(ŝᵀ ◦ NTT(u)) + m ← ByteEncode₁(Compress₁(w)) + return m + ``` + + The NIST FIPS 203 standard can be found at + . +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.decrypt_unpacked +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- CIPHERTEXT_SIZE= 1088 +- VECTOR_U_ENCODED_SIZE= 960 +- U_COMPRESSION_FACTOR= 10 +- V_COMPRESSION_FACTOR= 4 +*/ +static inline void libcrux_ml_kem_ind_cpa_decrypt_unpacked_6d( + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_f8 *secret_key, + uint8_t *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u_as_ntt[3U]; + libcrux_ml_kem_ind_cpa_deserialize_then_decompress_u_f4(ciphertext, u_as_ntt); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 v = + libcrux_ml_kem_serialize_deserialize_then_decompress_ring_element_v_56( + Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, + (size_t)960U, uint8_t, size_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 message = + libcrux_ml_kem_matrix_compute_message_b3(&v, secret_key->secret_as_ntt, + u_as_ntt); + uint8_t ret0[32U]; + libcrux_ml_kem_serialize_compress_then_serialize_message_aa(message, ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.decrypt +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- CIPHERTEXT_SIZE= 1088 +- VECTOR_U_ENCODED_SIZE= 960 +- U_COMPRESSION_FACTOR= 10 +- V_COMPRESSION_FACTOR= 4 +*/ +static inline void libcrux_ml_kem_ind_cpa_decrypt_43(Eurydice_slice secret_key, + uint8_t *ciphertext, + uint8_t ret[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U]; + libcrux_ml_kem_ind_cpa_deserialize_secret_key_24(secret_key, secret_as_ntt); + /* Passing arrays by value in Rust generates a copy in C */ + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 copy_of_secret_as_ntt[3U]; + memcpy( + copy_of_secret_as_ntt, secret_as_ntt, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + libcrux_ml_kem_ind_cpa_unpacked_IndCpaPrivateKeyUnpacked_f8 + secret_key_unpacked; + memcpy( + secret_key_unpacked.secret_as_ntt, copy_of_secret_as_ntt, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + uint8_t ret0[32U]; + libcrux_ml_kem_ind_cpa_decrypt_unpacked_6d(&secret_key_unpacked, ciphertext, + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.G_f1 +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_G_f1_e4( + Eurydice_slice input, uint8_t ret[64U]) { + libcrux_ml_kem_hash_functions_portable_G(input, ret); +} + +/** +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF +with const generics +- LEN= 32 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_2b( + Eurydice_slice input, uint8_t ret[32U]) { + uint8_t digest[32U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)32U, digest, uint8_t), input); + memcpy(ret, digest, (size_t)32U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF_f1 +with const generics +- K= 3 +- LEN= 32 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_f1_ee( + Eurydice_slice input, uint8_t ret[32U]) { + libcrux_ml_kem_hash_functions_portable_PRF_2b(input, ret); +} + +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_ring_elements_reduced.closure with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- PUBLIC_KEY_SIZE= 1152 +- K= 3 +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_closure_cd( + size_t _i) { + return libcrux_ml_kem_polynomial_ZERO_89_ea(); +} + +/** + Only use with public values. + + This MUST NOT be used with secret inputs, like its caller + `deserialize_ring_elements_reduced`. +*/ +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_to_reduced_ring_element with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element_4c( + Eurydice_slice serialized) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = + libcrux_ml_kem_polynomial_ZERO_89_ea(); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(serialized, uint8_t) / (size_t)24U; i++) { + size_t i0 = i; + Eurydice_slice bytes = Eurydice_slice_subslice2( + serialized, i0 * (size_t)24U, i0 * (size_t)24U + (size_t)24U, uint8_t); + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = + libcrux_ml_kem_vector_portable_deserialize_12_0d(bytes); + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_cond_subtract_3329_0d(coefficient); + re.coefficients[i0] = uu____0; + } + return re; +} + +/** + This function deserializes ring elements and reduces the result by the field + modulus. + + This function MUST NOT be used on secret inputs. +*/ +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_ring_elements_reduced with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- PUBLIC_KEY_SIZE= 1152 +- K= 3 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_33( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + deserialized_pk[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); + } + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(public_key, uint8_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice2( + public_key, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + uint8_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____0 = + libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element_4c( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); +} + +/** +A monomorphic instance of libcrux_ml_kem.matrix.sample_matrix_A.closure.closure +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_matrix_sample_matrix_A_closure_closure_78(size_t _j) { + return libcrux_ml_kem_polynomial_ZERO_89_ea(); +} + +/** +A monomorphic instance of libcrux_ml_kem.matrix.sample_matrix_A.closure +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +*/ +static inline void libcrux_ml_kem_matrix_sample_matrix_A_closure_4b( + size_t _i, libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + ret[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); + } +} + +/** +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PortableHash +with const generics +- $3size_t +*/ +typedef struct libcrux_ml_kem_hash_functions_portable_PortableHash_58_s { + libcrux_sha3_generic_keccak_KeccakState_48 shake128_state[3U]; +} libcrux_ml_kem_hash_functions_portable_PortableHash_58; + +/** +A monomorphic instance of +libcrux_ml_kem.hash_functions.portable.shake128_init_absorb with const generics +- K= 3 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_hash_functions_portable_PortableHash_58 +libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_b7( + uint8_t input[3U][34U]) { + libcrux_sha3_generic_keccak_KeccakState_48 shake128_state[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + shake128_state[i] = libcrux_sha3_portable_incremental_shake128_init(); + } + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + libcrux_sha3_portable_incremental_shake128_absorb_final( + &shake128_state[i0], + Eurydice_array_to_slice((size_t)34U, input[i0], uint8_t)); + } + /* Passing arrays by value in Rust generates a copy in C */ + libcrux_sha3_generic_keccak_KeccakState_48 copy_of_shake128_state[3U]; + memcpy(copy_of_shake128_state, shake128_state, + (size_t)3U * sizeof(libcrux_sha3_generic_keccak_KeccakState_48)); + libcrux_ml_kem_hash_functions_portable_PortableHash_58 lit; + memcpy(lit.shake128_state, copy_of_shake128_state, + (size_t)3U * sizeof(libcrux_sha3_generic_keccak_KeccakState_48)); + return lit; +} + +/** +This function found in impl {(libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.hash_functions.portable.shake128_init_absorb_f1 with const +generics +- K= 3 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_hash_functions_portable_PortableHash_58 +libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_f1_8c( + uint8_t input[3U][34U]) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_input[3U][34U]; + memcpy(copy_of_input, input, (size_t)3U * sizeof(uint8_t[34U])); + return libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_b7( + copy_of_input); +} + +/** +A monomorphic instance of +libcrux_ml_kem.hash_functions.portable.shake128_squeeze_three_blocks with const +generics +- K= 3 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_hash_functions_portable_shake128_squeeze_three_blocks_ca( + libcrux_ml_kem_hash_functions_portable_PortableHash_58 *st, + uint8_t ret[3U][504U]) { + uint8_t out[3U][504U] = {{0U}}; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + libcrux_sha3_portable_incremental_shake128_squeeze_first_three_blocks( + &st->shake128_state[i0], + Eurydice_array_to_slice((size_t)504U, out[i0], uint8_t)); + } + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[504U])); +} + +/** +This function found in impl {(libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.hash_functions.portable.shake128_squeeze_three_blocks_f1 with +const generics +- K= 3 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_hash_functions_portable_shake128_squeeze_three_blocks_f1_69( + libcrux_ml_kem_hash_functions_portable_PortableHash_58 *self, + uint8_t ret[3U][504U]) { + libcrux_ml_kem_hash_functions_portable_shake128_squeeze_three_blocks_ca(self, + ret); +} + +/** + If `bytes` contains a set of uniformly random bytes, this function + uniformly samples a ring element `â` that is treated as being the NTT + representation of the corresponding polynomial `a`. + + Since rejection sampling is used, it is possible the supplied bytes are + not enough to sample the element, in which case an `Err` is returned and the + caller must try again with a fresh set of bytes. + + This function partially implements Algorithm + 6 of the NIST FIPS 203 standard, We say "partially" because this + implementation only accepts a finite set of bytes as input and returns an error + if the set is not enough; Algorithm 6 of the FIPS 203 standard on the other + hand samples from an infinite stream of bytes until the ring element is filled. + Algorithm 6 is reproduced below: + + ```plaintext + Input: byte stream B ∈ 𝔹*. + Output: array â ∈ ℤ₂₅₆. + + i ← 0 + j ← 0 + while j < 256 do + d₁ ← B[i] + 256·(B[i+1] mod 16) + d₂ ← ⌊B[i+1]/16⌋ + 16·B[i+2] + if d₁ < q then + â[j] ← d₁ + j ← j + 1 + end if + if d₂ < q and j < 256 then + â[j] ← d₂ + j ← j + 1 + end if + i ← i + 3 + end while + return â + ``` + + The NIST FIPS 203 standard can be found at + . +*/ +/** +A monomorphic instance of +libcrux_ml_kem.sampling.sample_from_uniform_distribution_next with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 +- N= 504 +*/ +static KRML_MUSTINLINE bool +libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db( + uint8_t randomness[3U][504U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + for (size_t i0 = (size_t)0U; i0 < (size_t)3U; i0++) { + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)504U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = + Eurydice_array_to_subslice2(randomness[i1], r * (size_t)24U, + r * (size_t)24U + (size_t)24U, uint8_t); + size_t sampled = libcrux_ml_kem_vector_portable_rej_sample_0d( + uu____0, Eurydice_array_to_subslice2( + out[i1], sampled_coefficients[i1], + sampled_coefficients[i1] + (size_t)16U, int16_t)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + } + } + bool done = true; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { + done = false; + } + } + return done; +} + +/** +A monomorphic instance of +libcrux_ml_kem.hash_functions.portable.shake128_squeeze_block with const +generics +- K= 3 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_hash_functions_portable_shake128_squeeze_block_dd( + libcrux_ml_kem_hash_functions_portable_PortableHash_58 *st, + uint8_t ret[3U][168U]) { + uint8_t out[3U][168U] = {{0U}}; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + libcrux_sha3_portable_incremental_shake128_squeeze_next_block( + &st->shake128_state[i0], + Eurydice_array_to_slice((size_t)168U, out[i0], uint8_t)); + } + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[168U])); +} + +/** +This function found in impl {(libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +A monomorphic instance of +libcrux_ml_kem.hash_functions.portable.shake128_squeeze_block_f1 with const +generics +- K= 3 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_hash_functions_portable_shake128_squeeze_block_f1_60( + libcrux_ml_kem_hash_functions_portable_PortableHash_58 *self, + uint8_t ret[3U][168U]) { + libcrux_ml_kem_hash_functions_portable_shake128_squeeze_block_dd(self, ret); +} + +/** + If `bytes` contains a set of uniformly random bytes, this function + uniformly samples a ring element `â` that is treated as being the NTT + representation of the corresponding polynomial `a`. + + Since rejection sampling is used, it is possible the supplied bytes are + not enough to sample the element, in which case an `Err` is returned and the + caller must try again with a fresh set of bytes. + + This function partially implements Algorithm + 6 of the NIST FIPS 203 standard, We say "partially" because this + implementation only accepts a finite set of bytes as input and returns an error + if the set is not enough; Algorithm 6 of the FIPS 203 standard on the other + hand samples from an infinite stream of bytes until the ring element is filled. + Algorithm 6 is reproduced below: + + ```plaintext + Input: byte stream B ∈ 𝔹*. + Output: array â ∈ ℤ₂₅₆. + + i ← 0 + j ← 0 + while j < 256 do + d₁ ← B[i] + 256·(B[i+1] mod 16) + d₂ ← ⌊B[i+1]/16⌋ + 16·B[i+2] + if d₁ < q then + â[j] ← d₁ + j ← j + 1 + end if + if d₂ < q and j < 256 then + â[j] ← d₂ + j ← j + 1 + end if + i ← i + 3 + end while + return â + ``` + + The NIST FIPS 203 standard can be found at + . +*/ +/** +A monomorphic instance of +libcrux_ml_kem.sampling.sample_from_uniform_distribution_next with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- K= 3 +- N= 168 +*/ +static KRML_MUSTINLINE bool +libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db0( + uint8_t randomness[3U][168U], size_t *sampled_coefficients, + int16_t (*out)[272U]) { + for (size_t i0 = (size_t)0U; i0 < (size_t)3U; i0++) { + size_t i1 = i0; + for (size_t i = (size_t)0U; i < (size_t)168U / (size_t)24U; i++) { + size_t r = i; + if (sampled_coefficients[i1] < + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + Eurydice_slice uu____0 = + Eurydice_array_to_subslice2(randomness[i1], r * (size_t)24U, + r * (size_t)24U + (size_t)24U, uint8_t); + size_t sampled = libcrux_ml_kem_vector_portable_rej_sample_0d( + uu____0, Eurydice_array_to_subslice2( + out[i1], sampled_coefficients[i1], + sampled_coefficients[i1] + (size_t)16U, int16_t)); + size_t uu____1 = i1; + sampled_coefficients[uu____1] = sampled_coefficients[uu____1] + sampled; + } + } + } + bool done = true; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + if (sampled_coefficients[i0] >= + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT) { + sampled_coefficients[i0] = + LIBCRUX_ML_KEM_CONSTANTS_COEFFICIENTS_IN_RING_ELEMENT; + } else { + done = false; + } + } + return done; +} + +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.from_i16_array_89 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_polynomial_from_i16_array_89_c1(Eurydice_slice a) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result = + libcrux_ml_kem_polynomial_ZERO_89_ea(); + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_from_i16_array_0d( + Eurydice_slice_subslice2(a, i0 * (size_t)16U, + (i0 + (size_t)1U) * (size_t)16U, int16_t)); + result.coefficients[i0] = uu____0; + } + return result; +} + +/** +A monomorphic instance of libcrux_ml_kem.sampling.sample_from_xof.closure +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_sampling_sample_from_xof_closure_04(int16_t s[272U]) { + return libcrux_ml_kem_polynomial_from_i16_array_89_c1( + Eurydice_array_to_subslice2(s, (size_t)0U, (size_t)256U, int16_t)); +} + +/** +A monomorphic instance of libcrux_ml_kem.sampling.sample_from_xof +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_sampling_sample_from_xof_3f( + uint8_t seeds[3U][34U], + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { + size_t sampled_coefficients[3U] = {0U}; + int16_t out[3U][272U] = {{0U}}; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_seeds[3U][34U]; + memcpy(copy_of_seeds, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_ml_kem_hash_functions_portable_PortableHash_58 xof_state = + libcrux_ml_kem_hash_functions_portable_shake128_init_absorb_f1_8c( + copy_of_seeds); + uint8_t randomness0[3U][504U]; + libcrux_ml_kem_hash_functions_portable_shake128_squeeze_three_blocks_f1_69( + &xof_state, randomness0); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness0[3U][504U]; + memcpy(copy_of_randomness0, randomness0, (size_t)3U * sizeof(uint8_t[504U])); + bool done = libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db( + copy_of_randomness0, sampled_coefficients, out); + while (true) { + if (done) { + break; + } else { + uint8_t randomness[3U][168U]; + libcrux_ml_kem_hash_functions_portable_shake128_squeeze_block_f1_60( + &xof_state, randomness); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness[3U][168U]; + memcpy(copy_of_randomness, randomness, + (size_t)3U * sizeof(uint8_t[168U])); + done = libcrux_ml_kem_sampling_sample_from_uniform_distribution_next_db0( + copy_of_randomness, sampled_coefficients, out); + } + } + /* Passing arrays by value in Rust generates a copy in C */ + int16_t copy_of_out[3U][272U]; + memcpy(copy_of_out, out, (size_t)3U * sizeof(int16_t[272U])); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret0[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + ret0[i] = + libcrux_ml_kem_sampling_sample_from_xof_closure_04(copy_of_out[i]); + } + memcpy( + ret, ret0, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); +} + +/** +A monomorphic instance of libcrux_ml_kem.matrix.sample_matrix_A +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_matrix_sample_matrix_A_38( + uint8_t seed[34U], bool transpose, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U][3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A_transpose[3U][3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + libcrux_ml_kem_matrix_sample_matrix_A_closure_4b(i, A_transpose[i]); + } + for (size_t i0 = (size_t)0U; i0 < (size_t)3U; i0++) { + size_t i1 = i0; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_seed[34U]; + memcpy(copy_of_seed, seed, (size_t)34U * sizeof(uint8_t)); + uint8_t seeds[3U][34U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + memcpy(seeds[i], copy_of_seed, (size_t)34U * sizeof(uint8_t)); + } + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t j = i; + seeds[j][32U] = (uint8_t)i1; + seeds[j][33U] = (uint8_t)j; + } + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_seeds[3U][34U]; + memcpy(copy_of_seeds, seeds, (size_t)3U * sizeof(uint8_t[34U])); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 sampled[3U]; + libcrux_ml_kem_sampling_sample_from_xof_3f(copy_of_seeds, sampled); + for (size_t i = (size_t)0U; + i < Eurydice_slice_len( + Eurydice_array_to_slice( + (size_t)3U, sampled, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0), + libcrux_ml_kem_polynomial_PolynomialRingElement_f0); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 sample = sampled[j]; + if (transpose) { + A_transpose[j][i1] = sample; + } else { + A_transpose[i1][j] = sample; + } + } + } + memcpy(ret, A_transpose, + (size_t)3U * + sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U])); +} + +/** +A monomorphic instance of K. +with types libcrux_ml_kem_polynomial_PolynomialRingElement +libcrux_ml_kem_vector_portable_vector_type_PortableVector[3size_t], uint8_t + +*/ +typedef struct tuple_b0_s { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 fst[3U]; + uint8_t snd; +} tuple_b0; + +/** +A monomorphic instance of +libcrux_ml_kem.ind_cpa.sample_vector_cbd_then_ntt.closure with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- ETA= 2 +- ETA_RANDOMNESS_SIZE= 128 +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_closure_f7(size_t _i) { + return libcrux_ml_kem_polynomial_ZERO_89_ea(); +} + +/** +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN +with const generics +- K= 3 +- LEN= 128 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRFxN_c5( + uint8_t (*input)[33U], uint8_t ret[3U][128U]) { + uint8_t out[3U][128U] = {{0U}}; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, out[i0], uint8_t), + Eurydice_array_to_slice((size_t)33U, input[i0], uint8_t)); + } + memcpy(ret, out, (size_t)3U * sizeof(uint8_t[128U])); +} + +/** +This function found in impl {(libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRFxN_f1 +with const generics +- K= 3 +- LEN= 128 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRFxN_f1_93( + uint8_t (*input)[33U], uint8_t ret[3U][128U]) { + libcrux_ml_kem_hash_functions_portable_PRFxN_c5(input, ret); +} + +/** + Given a series of uniformly random bytes in `randomness`, for some number + `eta`, the `sample_from_binomial_distribution_{eta}` functions sample a ring + element from a binomial distribution centered at 0 that uses two sets of `eta` + coin flips. If, for example, `eta = ETA`, each ring coefficient is a value `v` + such such that `v ∈ {-ETA, -ETA + 1, ..., 0, ..., ETA + 1, ETA}` and: + + ```plaintext + - If v < 0, Pr[v] = Pr[-v] + - If v >= 0, Pr[v] = BINOMIAL_COEFFICIENT(2 * ETA; ETA - v) / 2 ^ (2 * ETA) + ``` + + The values `v < 0` are mapped to the appropriate `KyberFieldElement`. + + The expected value is: + + ```plaintext + E[X] = (-ETA)Pr[-ETA] + (-(ETA - 1))Pr[-(ETA - 1)] + ... + (ETA - 1)Pr[ETA - 1] + + (ETA)Pr[ETA] = 0 since Pr[-v] = Pr[v] when v < 0. + ``` + + And the variance is: + + ```plaintext + Var(X) = E[(X - E[X])^2] + = E[X^2] + = sum_(v=-ETA to ETA)v^2 * (BINOMIAL_COEFFICIENT(2 * ETA; ETA - v) / + 2^(2 * ETA)) = ETA / 2 + ``` + + This function implements Algorithm 7 of the NIST FIPS 203 + standard, which is reproduced below: + + ```plaintext + Input: byte array B ∈ 𝔹^{64η}. + Output: array f ∈ ℤ₂₅₆. + + b ← BytesToBits(B) + for (i ← 0; i < 256; i++) + x ← ∑(j=0 to η - 1) b[2iη + j] + y ← ∑(j=0 to η - 1) b[2iη + η + j] + f[i] ← x−y mod q + end for + return f + ``` + + The NIST FIPS 203 standard can be found at + . +*/ +/** +A monomorphic instance of +libcrux_ml_kem.sampling.sample_from_binomial_distribution_2 with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_sampling_sample_from_binomial_distribution_2_85( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < Eurydice_slice_len(randomness, uint8_t) / (size_t)4U; i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice2( + randomness, chunk_number * (size_t)4U, + chunk_number * (size_t)4U + (size_t)4U, uint8_t); + uint32_t random_bits_as_u32 = + (((uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t, + uint8_t *) | + (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t, + uint8_t *) + << 8U) | + (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, uint8_t, + uint8_t *) + << 16U) | + (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)3U, uint8_t, + uint8_t *) + << 24U; + uint32_t even_bits = random_bits_as_u32 & 1431655765U; + uint32_t odd_bits = random_bits_as_u32 >> 1U & 1431655765U; + uint32_t coin_toss_outcomes = even_bits + odd_bits; + for (uint32_t i = 0U; i < CORE_NUM__U32_8__BITS / 4U; i++) { + uint32_t outcome_set = i; + uint32_t outcome_set0 = outcome_set * 4U; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 3U); + int16_t outcome_2 = + (int16_t)(coin_toss_outcomes >> (uint32_t)(outcome_set0 + 2U) & 3U); + size_t offset = (size_t)(outcome_set0 >> 2U); + sampled_i16s[(size_t)8U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return libcrux_ml_kem_polynomial_from_i16_array_89_c1( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t)); +} + +/** +A monomorphic instance of +libcrux_ml_kem.sampling.sample_from_binomial_distribution_3 with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_sampling_sample_from_binomial_distribution_3_eb( + Eurydice_slice randomness) { + int16_t sampled_i16s[256U] = {0U}; + for (size_t i0 = (size_t)0U; + i0 < Eurydice_slice_len(randomness, uint8_t) / (size_t)3U; i0++) { + size_t chunk_number = i0; + Eurydice_slice byte_chunk = Eurydice_slice_subslice2( + randomness, chunk_number * (size_t)3U, + chunk_number * (size_t)3U + (size_t)3U, uint8_t); + uint32_t random_bits_as_u24 = + ((uint32_t)Eurydice_slice_index(byte_chunk, (size_t)0U, uint8_t, + uint8_t *) | + (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)1U, uint8_t, + uint8_t *) + << 8U) | + (uint32_t)Eurydice_slice_index(byte_chunk, (size_t)2U, uint8_t, + uint8_t *) + << 16U; + uint32_t first_bits = random_bits_as_u24 & 2396745U; + uint32_t second_bits = random_bits_as_u24 >> 1U & 2396745U; + uint32_t third_bits = random_bits_as_u24 >> 2U & 2396745U; + uint32_t coin_toss_outcomes = first_bits + second_bits + third_bits; + for (int32_t i = (int32_t)0; i < (int32_t)24 / (int32_t)6; i++) { + int32_t outcome_set = i; + int32_t outcome_set0 = outcome_set * (int32_t)6; + int16_t outcome_1 = + (int16_t)(coin_toss_outcomes >> (uint32_t)outcome_set0 & 7U); + int16_t outcome_2 = (int16_t)(coin_toss_outcomes >> + (uint32_t)(outcome_set0 + (int32_t)3) & + 7U); + size_t offset = (size_t)(outcome_set0 / (int32_t)6); + sampled_i16s[(size_t)4U * chunk_number + offset] = outcome_1 - outcome_2; + } + } + return libcrux_ml_kem_polynomial_from_i16_array_89_c1( + Eurydice_array_to_slice((size_t)256U, sampled_i16s, int16_t)); +} + +/** +A monomorphic instance of +libcrux_ml_kem.sampling.sample_from_binomial_distribution with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- ETA= 2 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_sampling_sample_from_binomial_distribution_c6( + Eurydice_slice randomness) { + return libcrux_ml_kem_sampling_sample_from_binomial_distribution_2_85( + randomness); +} + +/** +A monomorphic instance of libcrux_ml_kem.ntt.ntt_at_layer_7 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ntt_ntt_at_layer_7_f4( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re) { + size_t step = LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT / (size_t)2U; + for (size_t i = (size_t)0U; i < step; i++) { + size_t j = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector t = + libcrux_ml_kem_vector_portable_multiply_by_constant_0d( + re->coefficients[j + step], (int16_t)-1600); + re->coefficients[j + step] = + libcrux_ml_kem_vector_portable_sub_0d(re->coefficients[j], &t); + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____1 = + libcrux_ml_kem_vector_portable_add_0d(re->coefficients[j], &t); + re->coefficients[j] = uu____1; + } +} + +/** +A monomorphic instance of libcrux_ml_kem.ntt.ntt_binomially_sampled_ring_element +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element_0f( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re) { + libcrux_ml_kem_ntt_ntt_at_layer_7_f4(re); + size_t zeta_i = (size_t)1U; + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)6U, + (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)5U, + (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_4_plus_51(&zeta_i, re, (size_t)4U, + (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_3_fd(&zeta_i, re, (size_t)3U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_2_ad(&zeta_i, re, (size_t)2U, (size_t)3U); + libcrux_ml_kem_ntt_ntt_at_layer_1_a2(&zeta_i, re, (size_t)1U, (size_t)3U); + libcrux_ml_kem_polynomial_poly_barrett_reduce_89_8b(re); +} + +/** + Sample a vector of ring elements from a centered binomial distribution and + convert them into their NTT representations. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_vector_cbd_then_ntt +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- ETA= 2 +- ETA_RANDOMNESS_SIZE= 128 +*/ +static KRML_MUSTINLINE tuple_b0 +libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc(uint8_t prf_input[33U], + uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re_as_ntt[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + re_as_ntt[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); + } + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_prf_input[33U]; + memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)); + } + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U; + } + uint8_t prf_outputs[3U][128U]; + libcrux_ml_kem_hash_functions_portable_PRFxN_f1_93(prf_inputs, prf_outputs); + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + re_as_ntt[i0] = + libcrux_ml_kem_sampling_sample_from_binomial_distribution_c6( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], uint8_t)); + libcrux_ml_kem_ntt_ntt_binomially_sampled_ring_element_0f(&re_as_ntt[i0]); + } + /* Passing arrays by value in Rust generates a copy in C */ + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 copy_of_re_as_ntt[3U]; + memcpy( + copy_of_re_as_ntt, re_as_ntt, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + tuple_b0 lit; + memcpy( + lit.fst, copy_of_re_as_ntt, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + lit.snd = domain_separator; + return lit; +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_ring_element_cbd.closure +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- ETA2_RANDOMNESS_SIZE= 128 +- ETA2= 2 +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_closure_77(size_t _i) { + return libcrux_ml_kem_polynomial_ZERO_89_ea(); +} + +/** + Sample a vector of ring elements from a centered binomial distribution. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.sample_ring_element_cbd +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- ETA2_RANDOMNESS_SIZE= 128 +- ETA2= 2 +*/ +static KRML_MUSTINLINE tuple_b0 +libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_ac(uint8_t prf_input[33U], + uint8_t domain_separator) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_1[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + error_1[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); + } + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_prf_input[33U]; + memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t)); + uint8_t prf_inputs[3U][33U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + memcpy(prf_inputs[i], copy_of_prf_input, (size_t)33U * sizeof(uint8_t)); + } + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + prf_inputs[i0][32U] = domain_separator; + domain_separator = (uint32_t)domain_separator + 1U; + } + uint8_t prf_outputs[3U][128U]; + libcrux_ml_kem_hash_functions_portable_PRFxN_f1_93(prf_inputs, prf_outputs); + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____1 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution_c6( + Eurydice_array_to_slice((size_t)128U, prf_outputs[i0], uint8_t)); + error_1[i0] = uu____1; + } + /* Passing arrays by value in Rust generates a copy in C */ + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 copy_of_error_1[3U]; + memcpy( + copy_of_error_1, error_1, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + tuple_b0 lit; + memcpy( + lit.fst, copy_of_error_1, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + lit.snd = domain_separator; + return lit; +} + +/** +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF +with const generics +- LEN= 128 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_2b0( + Eurydice_slice input, uint8_t ret[128U]) { + uint8_t digest[128U] = {0U}; + libcrux_sha3_portable_shake256( + Eurydice_array_to_slice((size_t)128U, digest, uint8_t), input); + memcpy(ret, digest, (size_t)128U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.PRF_f1 +with const generics +- K= 3 +- LEN= 128 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_PRF_f1_ee0( + Eurydice_slice input, uint8_t ret[128U]) { + libcrux_ml_kem_hash_functions_portable_PRF_2b0(input, ret); +} + +/** +A monomorphic instance of libcrux_ml_kem.matrix.compute_vector_u.closure +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_matrix_compute_vector_u_closure_d6(size_t _i) { + return libcrux_ml_kem_polynomial_ZERO_89_ea(); +} + +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.add_error_reduce_89 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_polynomial_add_error_reduce_89_38( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t j = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector + coefficient_normal_form = + libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d( + self->coefficients[j], (int16_t)1441); + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_barrett_reduce_0d( + libcrux_ml_kem_vector_portable_add_0d(coefficient_normal_form, + &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +/** + Compute u := InvertNTT(Aᵀ ◦ r̂) + e₁ +*/ +/** +A monomorphic instance of libcrux_ml_kem.matrix.compute_vector_u +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_matrix_compute_vector_u_59( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 (*a_as_ntt)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error_1, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + result[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); + } + for (size_t i0 = (size_t)0U; + i0 < Eurydice_slice_len( + Eurydice_array_to_slice( + (size_t)3U, a_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U]), + libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U]); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *row = a_as_ntt[i1]; + for (size_t i = (size_t)0U; + i < Eurydice_slice_len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0), + libcrux_ml_kem_polynomial_PolynomialRingElement_f0); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *a_element = &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product = + libcrux_ml_kem_polynomial_ntt_multiply_89_2a(a_element, &r_as_ntt[j]); + libcrux_ml_kem_polynomial_add_to_ring_element_89_84(&result[i1], + &product); + } + libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_f6(&result[i1]); + libcrux_ml_kem_polynomial_add_error_reduce_89_38(&result[i1], &error_1[i1]); + } + memcpy( + ret, result, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); +} + +/** +A monomorphic instance of libcrux_ml_kem.vector.traits.decompress_1 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_traits_decompress_1_63( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_ZERO_0d(); + return libcrux_ml_kem_vector_portable_bitwise_and_with_constant_0d( + libcrux_ml_kem_vector_portable_sub_0d(uu____0, &v), (int16_t)1665); +} + +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_then_decompress_message with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_serialize_deserialize_then_decompress_message_0d( + uint8_t serialized[32U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = + libcrux_ml_kem_polynomial_ZERO_89_ea(); + for (size_t i = (size_t)0U; i < (size_t)16U; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector + coefficient_compressed = + libcrux_ml_kem_vector_portable_deserialize_1_0d( + Eurydice_array_to_subslice2(serialized, (size_t)2U * i0, + (size_t)2U * i0 + (size_t)2U, + uint8_t)); + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_traits_decompress_1_63(coefficient_compressed); + re.coefficients[i0] = uu____0; + } + return re; +} + +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.add_message_error_reduce_89 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_polynomial_add_message_error_reduce_89_ea( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *message, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector + coefficient_normal_form = + libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d( + result.coefficients[i0], (int16_t)1441); + libcrux_ml_kem_vector_portable_vector_type_PortableVector tmp = + libcrux_ml_kem_vector_portable_add_0d(self->coefficients[i0], + &message->coefficients[i0]); + libcrux_ml_kem_vector_portable_vector_type_PortableVector tmp0 = + libcrux_ml_kem_vector_portable_add_0d(coefficient_normal_form, &tmp); + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_barrett_reduce_0d(tmp0); + result.coefficients[i0] = uu____0; + } + return result; +} + +/** + Compute InverseNTT(tᵀ ◦ r̂) + e₂ + message +*/ +/** +A monomorphic instance of libcrux_ml_kem.matrix.compute_ring_element_v +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_matrix_compute_ring_element_v_54( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *t_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *r_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error_2, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *message) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result = + libcrux_ml_kem_polynomial_ZERO_89_ea(); + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product = + libcrux_ml_kem_polynomial_ntt_multiply_89_2a(&t_as_ntt[i0], + &r_as_ntt[i0]); + libcrux_ml_kem_polynomial_add_to_ring_element_89_84(&result, &product); + } + libcrux_ml_kem_invert_ntt_invert_ntt_montgomery_f6(&result); + result = libcrux_ml_kem_polynomial_add_message_error_reduce_89_ea( + error_2, message, result); + return result; +} + +/** +A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress +with const generics +- COEFFICIENT_BITS= 10 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_compress_02( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int16_t uu____0 = + libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( + (uint8_t)(int32_t)10, (uint16_t)v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +/** +A monomorphic instance of libcrux_ml_kem.vector.portable.compress_0d +with const generics +- COEFFICIENT_BITS= 10 +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_0d_28( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + return libcrux_ml_kem_vector_portable_compress_compress_02(v); +} + +/** +A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_10 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- OUT_LEN= 320 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_serialize_compress_then_serialize_10_fc( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = + libcrux_ml_kem_vector_portable_compress_0d_28( + libcrux_ml_kem_vector_traits_to_unsigned_representative_db( + re->coefficients[i0])); + uint8_t bytes[20U]; + libcrux_ml_kem_vector_portable_serialize_10_0d(coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice2( + serialized, (size_t)20U * i0, (size_t)20U * i0 + (size_t)20U, uint8_t); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)20U, bytes, uint8_t), uint8_t); + } + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); +} + +/** +A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress +with const generics +- COEFFICIENT_BITS= 11 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_compress_020( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int16_t uu____0 = + libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( + (uint8_t)(int32_t)11, (uint16_t)v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +/** +A monomorphic instance of libcrux_ml_kem.vector.portable.compress_0d +with const generics +- COEFFICIENT_BITS= 11 +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_0d_280( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + return libcrux_ml_kem_vector_portable_compress_compress_020(v); +} + +/** +A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_11 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- OUT_LEN= 320 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_serialize_compress_then_serialize_11_e1( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, uint8_t ret[320U]) { + uint8_t serialized[320U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = + libcrux_ml_kem_vector_portable_compress_0d_280( + libcrux_ml_kem_vector_traits_to_unsigned_representative_db( + re->coefficients[i0])); + uint8_t bytes[22U]; + libcrux_ml_kem_vector_portable_serialize_11_0d(coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice2( + serialized, (size_t)22U * i0, (size_t)22U * i0 + (size_t)22U, uint8_t); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)22U, bytes, uint8_t), uint8_t); + } + memcpy(ret, serialized, (size_t)320U * sizeof(uint8_t)); +} + +/** +A monomorphic instance of +libcrux_ml_kem.serialize.compress_then_serialize_ring_element_u with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- COMPRESSION_FACTOR= 10 +- OUT_LEN= 320 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u_5f( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, uint8_t ret[320U]) { + uint8_t uu____0[320U]; + libcrux_ml_kem_serialize_compress_then_serialize_10_fc(re, uu____0); + memcpy(ret, uu____0, (size_t)320U * sizeof(uint8_t)); +} + +/** + Call [`compress_then_serialize_ring_element_u`] on each ring element. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.compress_then_serialize_u +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- OUT_LEN= 960 +- COMPRESSION_FACTOR= 10 +- BLOCK_LEN= 320 +*/ +static inline void libcrux_ml_kem_ind_cpa_compress_then_serialize_u_a7( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 input[3U], + Eurydice_slice out) { + for (size_t i = (size_t)0U; + i < Eurydice_slice_len( + Eurydice_array_to_slice( + (size_t)3U, input, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0), + libcrux_ml_kem_polynomial_PolynomialRingElement_f0); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = input[i0]; + Eurydice_slice uu____0 = Eurydice_slice_subslice2( + out, i0 * ((size_t)960U / (size_t)3U), + (i0 + (size_t)1U) * ((size_t)960U / (size_t)3U), uint8_t); + uint8_t ret[320U]; + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_u_5f(&re, + ret); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)320U, ret, uint8_t), uint8_t); + } +} + +/** +A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress +with const generics +- COEFFICIENT_BITS= 4 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_compress_021( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int16_t uu____0 = + libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( + (uint8_t)(int32_t)4, (uint16_t)v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +/** +A monomorphic instance of libcrux_ml_kem.vector.portable.compress_0d +with const generics +- COEFFICIENT_BITS= 4 +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_0d_281( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + return libcrux_ml_kem_vector_portable_compress_compress_021(v); +} + +/** +A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_4 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_serialize_compress_then_serialize_4_9a( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = + libcrux_ml_kem_vector_portable_compress_0d_281( + libcrux_ml_kem_vector_traits_to_unsigned_representative_db( + re.coefficients[i0])); + uint8_t bytes[8U]; + libcrux_ml_kem_vector_portable_serialize_4_0d(coefficient, bytes); + Eurydice_slice_copy( + Eurydice_slice_subslice2(serialized, (size_t)8U * i0, + (size_t)8U * i0 + (size_t)8U, uint8_t), + Eurydice_array_to_slice((size_t)8U, bytes, uint8_t), uint8_t); + } +} + +/** +A monomorphic instance of libcrux_ml_kem.vector.portable.compress.compress +with const generics +- COEFFICIENT_BITS= 5 +*/ +static KRML_MUSTINLINE libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_compress_022( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_VECTOR_TRAITS_FIELD_ELEMENTS_IN_VECTOR; i++) { + size_t i0 = i; + int16_t uu____0 = + libcrux_ml_kem_vector_portable_compress_compress_ciphertext_coefficient( + (uint8_t)(int32_t)5, (uint16_t)v.elements[i0]); + v.elements[i0] = uu____0; + } + return v; +} + +/** +This function found in impl {(libcrux_ml_kem::vector::traits::Operations for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +/** +A monomorphic instance of libcrux_ml_kem.vector.portable.compress_0d +with const generics +- COEFFICIENT_BITS= 5 +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_compress_0d_282( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + return libcrux_ml_kem_vector_portable_compress_compress_022(v); +} + +/** +A monomorphic instance of libcrux_ml_kem.serialize.compress_then_serialize_5 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_serialize_compress_then_serialize_5_1f( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re, + Eurydice_slice serialized) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficients = + libcrux_ml_kem_vector_portable_compress_0d_282( + libcrux_ml_kem_vector_traits_to_unsigned_representative_db( + re.coefficients[i0])); + uint8_t bytes[10U]; + libcrux_ml_kem_vector_portable_serialize_5_0d(coefficients, bytes); + Eurydice_slice_copy( + Eurydice_slice_subslice2(serialized, (size_t)10U * i0, + (size_t)10U * i0 + (size_t)10U, uint8_t), + Eurydice_array_to_slice((size_t)10U, bytes, uint8_t), uint8_t); + } +} + +/** +A monomorphic instance of +libcrux_ml_kem.serialize.compress_then_serialize_ring_element_v with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- COMPRESSION_FACTOR= 4 +- OUT_LEN= 128 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_4e( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re, Eurydice_slice out) { + libcrux_ml_kem_serialize_compress_then_serialize_4_9a(re, out); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.encrypt +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] with const +generics +- K= 3 +- CIPHERTEXT_SIZE= 1088 +- T_AS_NTT_ENCODED_SIZE= 1152 +- C1_LEN= 960 +- C2_LEN= 128 +- U_COMPRESSION_FACTOR= 10 +- V_COMPRESSION_FACTOR= 4 +- BLOCK_LEN= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +- ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 +*/ +static inline void libcrux_ml_kem_ind_cpa_encrypt_60(Eurydice_slice public_key, + uint8_t message[32U], + Eurydice_slice randomness, + uint8_t ret[1088U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 t_as_ntt[3U]; + libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_33( + Eurydice_slice_subslice_to(public_key, (size_t)1152U, uint8_t, size_t), + t_as_ntt); + Eurydice_slice seed = + Eurydice_slice_subslice_from(public_key, (size_t)1152U, uint8_t, size_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A[3U][3U]; + uint8_t ret0[34U]; + libcrux_ml_kem_utils_into_padded_array_ea1(seed, ret0); + libcrux_ml_kem_matrix_sample_matrix_A_38(ret0, false, A); + uint8_t prf_input[33U]; + libcrux_ml_kem_utils_into_padded_array_ea2(randomness, prf_input); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_prf_input0[33U]; + memcpy(copy_of_prf_input0, prf_input, (size_t)33U * sizeof(uint8_t)); + tuple_b0 uu____1 = libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc( + copy_of_prf_input0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 r_as_ntt[3U]; + memcpy( + r_as_ntt, uu____1.fst, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + uint8_t domain_separator0 = uu____1.snd; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_prf_input[33U]; + memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t)); + tuple_b0 uu____3 = libcrux_ml_kem_ind_cpa_sample_ring_element_cbd_ac( + copy_of_prf_input, domain_separator0); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_1[3U]; + memcpy( + error_1, uu____3.fst, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + uint8_t domain_separator = uu____3.snd; + prf_input[32U] = domain_separator; + uint8_t prf_output[128U]; + libcrux_ml_kem_hash_functions_portable_PRF_f1_ee0( + Eurydice_array_to_slice((size_t)33U, prf_input, uint8_t), prf_output); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_2 = + libcrux_ml_kem_sampling_sample_from_binomial_distribution_c6( + Eurydice_array_to_slice((size_t)128U, prf_output, uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 u[3U]; + libcrux_ml_kem_matrix_compute_vector_u_59(A, r_as_ntt, error_1, u); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_message[32U]; + memcpy(copy_of_message, message, (size_t)32U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 message_as_ring_element = + libcrux_ml_kem_serialize_deserialize_then_decompress_message_0d( + copy_of_message); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 v = + libcrux_ml_kem_matrix_compute_ring_element_v_54( + t_as_ntt, r_as_ntt, &error_2, &message_as_ring_element); + uint8_t ciphertext[1088U] = {0U}; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____5[3U]; + memcpy( + uu____5, u, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + libcrux_ml_kem_ind_cpa_compress_then_serialize_u_a7( + uu____5, Eurydice_array_to_subslice2(ciphertext, (size_t)0U, (size_t)960U, + uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____6 = v; + libcrux_ml_kem_serialize_compress_then_serialize_ring_element_v_4e( + uu____6, Eurydice_array_to_subslice_from((size_t)1088U, ciphertext, + (size_t)960U, uint8_t, size_t)); + memcpy(ret, ciphertext, (size_t)1088U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_ml_kem::variant::Variant for +libcrux_ml_kem::variant::MlKem)#1} +*/ +/** +A monomorphic instance of libcrux_ml_kem.variant.kdf_d8 +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +- CIPHERTEXT_SIZE= 1088 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_variant_kdf_d8_41( + Eurydice_slice shared_secret, libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_, + uint8_t ret[32U]) { + uint8_t out[32U] = {0U}; + Eurydice_slice_copy(Eurydice_array_to_slice((size_t)32U, out, uint8_t), + shared_secret, uint8_t); + memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.decapsulate +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_variant_MlKem with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- CIPHERTEXT_SIZE= 1088 +- T_AS_NTT_ENCODED_SIZE= 1152 +- C1_SIZE= 960 +- C2_SIZE= 128 +- VECTOR_U_COMPRESSION_FACTOR= 10 +- VECTOR_V_COMPRESSION_FACTOR= 4 +- C1_BLOCK_SIZE= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +- ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 +- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120 +*/ +static inline void libcrux_ml_kem_ind_cca_decapsulate_70( + libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t), + (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( + secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + libcrux_ml_kem_ind_cpa_decrypt_43(ind_cpa_secret_key, ciphertext->value, + decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_utils_into_padded_array_ea( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t), to_hash0); + Eurydice_slice_copy( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t), + ind_cpa_public_key_hash, uint8_t); + uint8_t hashed[64U]; + libcrux_ml_kem_hash_functions_portable_G_f1_e4( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); + Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + Eurydice_slice_uint8_t_x2); + Eurydice_slice shared_secret0 = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1120U]; + libcrux_ml_kem_utils_into_padded_array_ea0(implicit_rejection_value, to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t); + Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_24(ciphertext), + uint8_t); + uint8_t implicit_rejection_shared_secret0[32U]; + libcrux_ml_kem_hash_functions_portable_PRF_f1_ee( + Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t), + implicit_rejection_shared_secret0); + Eurydice_slice uu____5 = ind_cpa_public_key; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_decrypted[32U]; + memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[1088U]; + libcrux_ml_kem_ind_cpa_encrypt_60(uu____5, copy_of_decrypted, + pseudorandomness, expected_ciphertext); + uint8_t implicit_rejection_shared_secret[32U]; + libcrux_ml_kem_variant_kdf_d8_41( + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret0, + uint8_t), + ciphertext, implicit_rejection_shared_secret); + uint8_t shared_secret[32U]; + libcrux_ml_kem_variant_kdf_d8_41(shared_secret0, ciphertext, shared_secret); + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( + libcrux_ml_kem_types_as_ref_00_24(ciphertext), + Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t), + Eurydice_array_to_slice((size_t)32U, shared_secret, uint8_t), + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t), + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +/** + Portable decapsulate +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.decapsulate with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- CIPHERTEXT_SIZE= 1088 +- T_AS_NTT_ENCODED_SIZE= 1152 +- C1_SIZE= 960 +- C2_SIZE= 128 +- VECTOR_U_COMPRESSION_FACTOR= 10 +- VECTOR_V_COMPRESSION_FACTOR= 4 +- C1_BLOCK_SIZE= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +- ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 +- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120 +*/ +static inline void +libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate_2e( + libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_ind_cca_decapsulate_70(private_key, ciphertext, ret); +} + +/** + Decapsulate ML-KEM 768 + + Generates an [`MlKemSharedSecret`]. + The input is a reference to an [`MlKem768PrivateKey`] and an + [`MlKem768Ciphertext`]. +*/ +static inline void libcrux_ml_kem_mlkem768_portable_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_ind_cca_instantiations_portable_decapsulate_2e( + private_key, ciphertext, ret); +} + +/** +This function found in impl {(libcrux_ml_kem::variant::Variant for +libcrux_ml_kem::variant::MlKem)#1} +*/ +/** +A monomorphic instance of libcrux_ml_kem.variant.entropy_preprocess_d8 +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_variant_entropy_preprocess_d8_63( + Eurydice_slice randomness, uint8_t ret[32U]) { + uint8_t out[32U] = {0U}; + Eurydice_slice_copy(Eurydice_array_to_slice((size_t)32U, out, uint8_t), + randomness, uint8_t); + memcpy(ret, out, (size_t)32U * sizeof(uint8_t)); +} + +/** +This function found in impl {(libcrux_ml_kem::hash_functions::Hash for +libcrux_ml_kem::hash_functions::portable::PortableHash)} +*/ +/** +A monomorphic instance of libcrux_ml_kem.hash_functions.portable.H_f1 +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_hash_functions_portable_H_f1_1a( + Eurydice_slice input, uint8_t ret[32U]) { + libcrux_ml_kem_hash_functions_portable_H(input, ret); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.encapsulate +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_variant_MlKem with const generics +- K= 3 +- CIPHERTEXT_SIZE= 1088 +- PUBLIC_KEY_SIZE= 1184 +- T_AS_NTT_ENCODED_SIZE= 1152 +- C1_SIZE= 960 +- C2_SIZE= 128 +- VECTOR_U_COMPRESSION_FACTOR= 10 +- VECTOR_V_COMPRESSION_FACTOR= 4 +- VECTOR_U_BLOCK_LEN= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +- ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 +*/ +static inline tuple_3c libcrux_ml_kem_ind_cca_encapsulate_cd( + libcrux_ml_kem_types_MlKemPublicKey_15 *public_key, + uint8_t randomness[32U]) { + uint8_t randomness0[32U]; + libcrux_ml_kem_variant_entropy_preprocess_d8_63( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t), randomness0); + uint8_t to_hash[64U]; + libcrux_ml_kem_utils_into_padded_array_ea( + Eurydice_array_to_slice((size_t)32U, randomness0, uint8_t), to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t); + uint8_t ret[32U]; + libcrux_ml_kem_hash_functions_portable_H_f1_1a( + Eurydice_array_to_slice((size_t)1184U, + libcrux_ml_kem_types_as_slice_cb_50(public_key), + uint8_t), + ret); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); + uint8_t hashed[64U]; + libcrux_ml_kem_hash_functions_portable_G_f1_e4( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t), hashed); + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + Eurydice_slice_uint8_t_x2); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1184U, libcrux_ml_kem_types_as_slice_cb_50(public_key), uint8_t); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness[32U]; + memcpy(copy_of_randomness, randomness0, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[1088U]; + libcrux_ml_kem_ind_cpa_encrypt_60(uu____2, copy_of_randomness, + pseudorandomness, ciphertext); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_ciphertext[1088U]; + memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext ciphertext0 = + libcrux_ml_kem_types_from_01_9f(copy_of_ciphertext); + uint8_t shared_secret_array[32U]; + libcrux_ml_kem_variant_kdf_d8_41(shared_secret, &ciphertext0, + shared_secret_array); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = ciphertext0; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_shared_secret_array[32U]; + memcpy(copy_of_shared_secret_array, shared_secret_array, + (size_t)32U * sizeof(uint8_t)); + tuple_3c lit; + lit.fst = uu____5; + memcpy(lit.snd, copy_of_shared_secret_array, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.encapsulate with const generics +- K= 3 +- CIPHERTEXT_SIZE= 1088 +- PUBLIC_KEY_SIZE= 1184 +- T_AS_NTT_ENCODED_SIZE= 1152 +- C1_SIZE= 960 +- C2_SIZE= 128 +- VECTOR_U_COMPRESSION_FACTOR= 10 +- VECTOR_V_COMPRESSION_FACTOR= 4 +- VECTOR_U_BLOCK_LEN= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +- ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 +*/ +static inline tuple_3c +libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate_c6( + libcrux_ml_kem_types_MlKemPublicKey_15 *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey_15 *uu____0 = public_key; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness[32U]; + memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate_cd(uu____0, copy_of_randomness); +} + +/** + Encapsulate ML-KEM 768 + + Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. + The input is a reference to an [`MlKem768PublicKey`] and [`SHARED_SECRET_SIZE`] + bytes of `randomness`. +*/ +static inline tuple_3c libcrux_ml_kem_mlkem768_portable_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey_15 *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey_15 *uu____0 = public_key; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness[32U]; + memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_encapsulate_c6( + uu____0, copy_of_randomness); +} + +/** +This function found in impl {(libcrux_ml_kem::variant::Variant for +libcrux_ml_kem::variant::MlKem)#1} +*/ +/** +A monomorphic instance of libcrux_ml_kem.variant.cpa_keygen_seed_d8 +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_variant_cpa_keygen_seed_d8_0e( + Eurydice_slice key_generation_seed, uint8_t ret[64U]) { + uint8_t seed[33U] = {0U}; + Eurydice_slice_copy( + Eurydice_array_to_subslice2( + seed, (size_t)0U, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t), + key_generation_seed, uint8_t); + seed[LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE] = + (uint8_t)(size_t)3U; + uint8_t ret0[64U]; + libcrux_ml_kem_hash_functions_portable_G_f1_e4( + Eurydice_array_to_slice((size_t)33U, seed, uint8_t), ret0); + memcpy(ret, ret0, (size_t)64U * sizeof(uint8_t)); +} + +/** +A monomorphic instance of libcrux_ml_kem.matrix.compute_As_plus_e.closure +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_matrix_compute_As_plus_e_closure_87(size_t _i) { + return libcrux_ml_kem_polynomial_ZERO_89_ea(); +} + +/** +A monomorphic instance of libcrux_ml_kem.vector.traits.to_standard_domain +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_traits_to_standard_domain_59( + libcrux_ml_kem_vector_portable_vector_type_PortableVector v) { + return libcrux_ml_kem_vector_portable_montgomery_multiply_by_constant_0d( + v, LIBCRUX_ML_KEM_VECTOR_TRAITS_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS); +} + +/** +This function found in impl +{libcrux_ml_kem::polynomial::PolynomialRingElement[TraitClause@0]} +*/ +/** +A monomorphic instance of libcrux_ml_kem.polynomial.add_standard_error_reduce_89 +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics + +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_polynomial_add_standard_error_reduce_89_03( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *self, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error) { + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t j = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector + coefficient_normal_form = + libcrux_ml_kem_vector_traits_to_standard_domain_59( + self->coefficients[j]); + libcrux_ml_kem_vector_portable_vector_type_PortableVector uu____0 = + libcrux_ml_kem_vector_portable_barrett_reduce_0d( + libcrux_ml_kem_vector_portable_add_0d(coefficient_normal_form, + &error->coefficients[j])); + self->coefficients[j] = uu____0; + } +} + +/** + Compute  ◦ ŝ + ê +*/ +/** +A monomorphic instance of libcrux_ml_kem.matrix.compute_As_plus_e +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_matrix_compute_As_plus_e_60( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 (*matrix_A)[3U], + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *s_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *error_as_ntt, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 result[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + result[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); + } + for (size_t i0 = (size_t)0U; + i0 < Eurydice_slice_len( + Eurydice_array_to_slice( + (size_t)3U, matrix_A, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U]), + libcrux_ml_kem_polynomial_PolynomialRingElement_f0[3U]); + i0++) { + size_t i1 = i0; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *row = matrix_A[i1]; + for (size_t i = (size_t)0U; + i < Eurydice_slice_len( + Eurydice_array_to_slice( + (size_t)3U, row, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0), + libcrux_ml_kem_polynomial_PolynomialRingElement_f0); + i++) { + size_t j = i; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *matrix_element = + &row[j]; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 product = + libcrux_ml_kem_polynomial_ntt_multiply_89_2a(matrix_element, + &s_as_ntt[j]); + libcrux_ml_kem_polynomial_add_to_ring_element_89_84(&result[i1], + &product); + } + libcrux_ml_kem_polynomial_add_standard_error_reduce_89_03( + &result[i1], &error_as_ntt[i1]); + } + memcpy( + ret, result, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); +} + +/** +A monomorphic instance of +libcrux_ml_kem.serialize.serialize_uncompressed_ring_element with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics + +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_serialize_serialize_uncompressed_ring_element_5b( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *re, uint8_t ret[384U]) { + uint8_t serialized[384U] = {0U}; + for (size_t i = (size_t)0U; + i < LIBCRUX_ML_KEM_POLYNOMIAL_VECTORS_IN_RING_ELEMENT; i++) { + size_t i0 = i; + libcrux_ml_kem_vector_portable_vector_type_PortableVector coefficient = + libcrux_ml_kem_vector_traits_to_unsigned_representative_db( + re->coefficients[i0]); + uint8_t bytes[24U]; + libcrux_ml_kem_vector_portable_serialize_12_0d(coefficient, bytes); + Eurydice_slice uu____0 = Eurydice_array_to_subslice2( + serialized, (size_t)24U * i0, (size_t)24U * i0 + (size_t)24U, uint8_t); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)24U, bytes, uint8_t), uint8_t); + } + memcpy(ret, serialized, (size_t)384U * sizeof(uint8_t)); +} + +/** + Call [`serialize_uncompressed_ring_element`] for each ring element. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_secret_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- OUT_LEN= 1152 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_serialize_secret_key_b5( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *key, + uint8_t ret[1152U]) { + uint8_t out[1152U] = {0U}; + for (size_t i = (size_t)0U; + i < Eurydice_slice_len( + Eurydice_array_to_slice( + (size_t)3U, key, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0), + libcrux_ml_kem_polynomial_PolynomialRingElement_f0); + i++) { + size_t i0 = i; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 re = key[i0]; + Eurydice_slice uu____0 = Eurydice_array_to_subslice2( + out, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + (i0 + (size_t)1U) * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + uint8_t); + uint8_t ret0[384U]; + libcrux_ml_kem_serialize_serialize_uncompressed_ring_element_5b(&re, ret0); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)384U, ret0, uint8_t), uint8_t); + } + memcpy(ret, out, (size_t)1152U * sizeof(uint8_t)); +} + +/** + Concatenate `t` and `ρ` into the public key. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.serialize_public_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cpa_serialize_public_key_79( + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *t_as_ntt, + Eurydice_slice seed_for_a, uint8_t ret[1184U]) { + uint8_t public_key_serialized[1184U] = {0U}; + Eurydice_slice uu____0 = Eurydice_array_to_subslice2( + public_key_serialized, (size_t)0U, (size_t)1152U, uint8_t); + uint8_t ret0[1152U]; + libcrux_ml_kem_ind_cpa_serialize_secret_key_b5(t_as_ntt, ret0); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)1152U, ret0, uint8_t), uint8_t); + Eurydice_slice_copy( + Eurydice_array_to_subslice_from((size_t)1184U, public_key_serialized, + (size_t)1152U, uint8_t, size_t), + seed_for_a, uint8_t); + memcpy(ret, public_key_serialized, (size_t)1184U * sizeof(uint8_t)); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_variant_MlKem with const generics +- K= 3 +- PRIVATE_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static inline libcrux_ml_kem_utils_extraction_helper_Keypair768 +libcrux_ml_kem_ind_cpa_generate_keypair_fc(Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + libcrux_ml_kem_variant_cpa_keygen_seed_d8_0e(key_generation_seed, hashed); + Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), (size_t)32U, + uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice seed_for_A0 = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A_transpose[3U][3U]; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array_ea1(seed_for_A0, ret); + libcrux_ml_kem_matrix_sample_matrix_A_38(ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_utils_into_padded_array_ea2(seed_for_secret_and_error, + prf_input); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_prf_input0[33U]; + memcpy(copy_of_prf_input0, prf_input, (size_t)33U * sizeof(uint8_t)); + tuple_b0 uu____2 = libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc( + copy_of_prf_input0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + uint8_t domain_separator = uu____2.snd; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_prf_input[33U]; + memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_as_ntt[3U]; + memcpy( + error_as_ntt, + libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc(copy_of_prf_input, + domain_separator) + .fst, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 t_as_ntt[3U]; + libcrux_ml_kem_matrix_compute_As_plus_e_60(A_transpose, secret_as_ntt, + error_as_ntt, t_as_ntt); + uint8_t seed_for_A[32U]; + Result_00 dst; + Eurydice_slice_to_array2(&dst, seed_for_A0, Eurydice_slice, uint8_t[32U]); + unwrap_41_83(dst, seed_for_A); + uint8_t public_key_serialized[1184U]; + libcrux_ml_kem_ind_cpa_serialize_public_key_79( + t_as_ntt, Eurydice_array_to_slice((size_t)32U, seed_for_A, uint8_t), + public_key_serialized); + uint8_t secret_key_serialized[1152U]; + libcrux_ml_kem_ind_cpa_serialize_secret_key_b5(secret_as_ntt, + secret_key_serialized); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_secret_key_serialized[1152U]; + memcpy(copy_of_secret_key_serialized, secret_key_serialized, + (size_t)1152U * sizeof(uint8_t)); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_public_key_serialized[1184U]; + memcpy(copy_of_public_key_serialized, public_key_serialized, + (size_t)1184U * sizeof(uint8_t)); + libcrux_ml_kem_utils_extraction_helper_Keypair768 lit; + memcpy(lit.fst, copy_of_secret_key_serialized, + (size_t)1152U * sizeof(uint8_t)); + memcpy(lit.snd, copy_of_public_key_serialized, + (size_t)1184U * sizeof(uint8_t)); + return lit; +} + +/** + Serialize the secret key. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.serialize_kem_secret_key +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +- SERIALIZED_KEY_LEN= 2400 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_ind_cca_serialize_kem_secret_key_48( + Eurydice_slice private_key, Eurydice_slice public_key, + Eurydice_slice implicit_rejection_value, uint8_t ret[2400U]) { + uint8_t out[2400U] = {0U}; + size_t pointer = (size_t)0U; + uint8_t *uu____0 = out; + size_t uu____1 = pointer; + size_t uu____2 = pointer; + Eurydice_slice_copy( + Eurydice_array_to_subslice2( + uu____0, uu____1, uu____2 + Eurydice_slice_len(private_key, uint8_t), + uint8_t), + private_key, uint8_t); + pointer = pointer + Eurydice_slice_len(private_key, uint8_t); + uint8_t *uu____3 = out; + size_t uu____4 = pointer; + size_t uu____5 = pointer; + Eurydice_slice_copy( + Eurydice_array_to_subslice2( + uu____3, uu____4, uu____5 + Eurydice_slice_len(public_key, uint8_t), + uint8_t), + public_key, uint8_t); + pointer = pointer + Eurydice_slice_len(public_key, uint8_t); + Eurydice_slice uu____6 = Eurydice_array_to_subslice2( + out, pointer, pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t); + uint8_t ret0[32U]; + libcrux_ml_kem_hash_functions_portable_H_f1_1a(public_key, ret0); + Eurydice_slice_copy( + uu____6, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); + pointer = pointer + LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE; + uint8_t *uu____7 = out; + size_t uu____8 = pointer; + size_t uu____9 = pointer; + Eurydice_slice_copy( + Eurydice_array_to_subslice2( + uu____7, uu____8, + uu____9 + Eurydice_slice_len(implicit_rejection_value, uint8_t), + uint8_t), + implicit_rejection_value, uint8_t); + memcpy(ret, out, (size_t)2400U * sizeof(uint8_t)); +} + +/** + Packed API + + Generate a key pair. + + Depending on the `Vector` and `Hasher` used, this requires different hardware + features +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.generate_keypair +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_variant_MlKem with const generics +- K= 3 +- CPA_PRIVATE_KEY_SIZE= 1152 +- PRIVATE_KEY_SIZE= 2400 +- PUBLIC_KEY_SIZE= 1184 +- BYTES_PER_RING_ELEMENT= 1152 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_generate_keypair_8c(uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice2( + randomness, (size_t)0U, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t); + libcrux_ml_kem_utils_extraction_helper_Keypair768 uu____0 = + libcrux_ml_kem_ind_cpa_generate_keypair_fc(ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); + uint8_t public_key[1184U]; + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + uint8_t secret_key_serialized[2400U]; + libcrux_ml_kem_ind_cca_serialize_kem_secret_key_48( + Eurydice_array_to_slice((size_t)1152U, ind_cpa_private_key, uint8_t), + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t), + implicit_rejection_value, secret_key_serialized); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_secret_key_serialized[2400U]; + memcpy(copy_of_secret_key_serialized, secret_key_serialized, + (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey_55 private_key = + libcrux_ml_kem_types_from_05_f2(copy_of_secret_key_serialized); + libcrux_ml_kem_types_MlKemPrivateKey_55 uu____2 = private_key; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_public_key[1184U]; + memcpy(copy_of_public_key, public_key, (size_t)1184U * sizeof(uint8_t)); + return libcrux_ml_kem_types_from_17_35( + uu____2, libcrux_ml_kem_types_from_b6_da(copy_of_public_key)); +} + +/** + Portable generate key pair. +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.generate_keypair with const +generics +- K= 3 +- CPA_PRIVATE_KEY_SIZE= 1152 +- PRIVATE_KEY_SIZE= 2400 +- PUBLIC_KEY_SIZE= 1184 +- BYTES_PER_RING_ELEMENT= 1152 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair_d5( + uint8_t randomness[64U]) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness[64U]; + memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair_8c(copy_of_randomness); +} + +/** + Generate ML-KEM 768 Key Pair +*/ +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_mlkem768_portable_generate_key_pair(uint8_t randomness[64U]) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness[64U]; + memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_generate_keypair_d5( + copy_of_randomness); +} + +/** +This function found in impl {(libcrux_ml_kem::variant::Variant for +libcrux_ml_kem::variant::Kyber)} +*/ +/** +A monomorphic instance of libcrux_ml_kem.variant.kdf_33 +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +- CIPHERTEXT_SIZE= 1088 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_variant_kdf_33_f0( + Eurydice_slice shared_secret, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + uint8_t kdf_input[64U]; + libcrux_ml_kem_utils_into_padded_array_ea(shared_secret, kdf_input); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, kdf_input, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t); + uint8_t ret0[32U]; + libcrux_ml_kem_hash_functions_portable_H_f1_1a( + Eurydice_array_to_slice((size_t)1088U, + libcrux_ml_kem_types_as_slice_d4_1d(ciphertext), + uint8_t), + ret0); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)32U, ret0, uint8_t), uint8_t); + uint8_t ret1[32U]; + libcrux_ml_kem_hash_functions_portable_PRF_f1_ee( + Eurydice_array_to_slice((size_t)64U, kdf_input, uint8_t), ret1); + memcpy(ret, ret1, (size_t)32U * sizeof(uint8_t)); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.decapsulate +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_variant_Kyber with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- CIPHERTEXT_SIZE= 1088 +- T_AS_NTT_ENCODED_SIZE= 1152 +- C1_SIZE= 960 +- C2_SIZE= 128 +- VECTOR_U_COMPRESSION_FACTOR= 10 +- VECTOR_V_COMPRESSION_FACTOR= 4 +- C1_BLOCK_SIZE= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +- ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 +- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120 +*/ +static inline void libcrux_ml_kem_ind_cca_decapsulate_700( + libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( + Eurydice_array_to_slice((size_t)2400U, private_key->value, uint8_t), + (size_t)1152U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_secret_key = uu____0.fst; + Eurydice_slice secret_key0 = uu____0.snd; + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( + secret_key0, (size_t)1184U, uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key = uu____1.fst; + Eurydice_slice secret_key = uu____1.snd; + Eurydice_slice_uint8_t_x2 uu____2 = Eurydice_slice_split_at( + secret_key, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + Eurydice_slice_uint8_t_x2); + Eurydice_slice ind_cpa_public_key_hash = uu____2.fst; + Eurydice_slice implicit_rejection_value = uu____2.snd; + uint8_t decrypted[32U]; + libcrux_ml_kem_ind_cpa_decrypt_43(ind_cpa_secret_key, ciphertext->value, + decrypted); + uint8_t to_hash0[64U]; + libcrux_ml_kem_utils_into_padded_array_ea( + Eurydice_array_to_slice((size_t)32U, decrypted, uint8_t), to_hash0); + Eurydice_slice_copy( + Eurydice_array_to_subslice_from( + (size_t)64U, to_hash0, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t), + ind_cpa_public_key_hash, uint8_t); + uint8_t hashed[64U]; + libcrux_ml_kem_hash_functions_portable_G_f1_e4( + Eurydice_array_to_slice((size_t)64U, to_hash0, uint8_t), hashed); + Eurydice_slice_uint8_t_x2 uu____3 = Eurydice_slice_split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + Eurydice_slice_uint8_t_x2); + Eurydice_slice shared_secret0 = uu____3.fst; + Eurydice_slice pseudorandomness = uu____3.snd; + uint8_t to_hash[1120U]; + libcrux_ml_kem_utils_into_padded_array_ea0(implicit_rejection_value, to_hash); + Eurydice_slice uu____4 = Eurydice_array_to_subslice_from( + (size_t)1120U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, + uint8_t, size_t); + Eurydice_slice_copy(uu____4, libcrux_ml_kem_types_as_ref_00_24(ciphertext), + uint8_t); + uint8_t implicit_rejection_shared_secret0[32U]; + libcrux_ml_kem_hash_functions_portable_PRF_f1_ee( + Eurydice_array_to_slice((size_t)1120U, to_hash, uint8_t), + implicit_rejection_shared_secret0); + Eurydice_slice uu____5 = ind_cpa_public_key; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_decrypted[32U]; + memcpy(copy_of_decrypted, decrypted, (size_t)32U * sizeof(uint8_t)); + uint8_t expected_ciphertext[1088U]; + libcrux_ml_kem_ind_cpa_encrypt_60(uu____5, copy_of_decrypted, + pseudorandomness, expected_ciphertext); + uint8_t implicit_rejection_shared_secret[32U]; + libcrux_ml_kem_variant_kdf_33_f0( + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret0, + uint8_t), + ciphertext, implicit_rejection_shared_secret); + uint8_t shared_secret[32U]; + libcrux_ml_kem_variant_kdf_33_f0(shared_secret0, ciphertext, shared_secret); + uint8_t ret0[32U]; + libcrux_ml_kem_constant_time_ops_compare_ciphertexts_select_shared_secret_in_constant_time( + libcrux_ml_kem_types_as_ref_00_24(ciphertext), + Eurydice_array_to_slice((size_t)1088U, expected_ciphertext, uint8_t), + Eurydice_array_to_slice((size_t)32U, shared_secret, uint8_t), + Eurydice_array_to_slice((size_t)32U, implicit_rejection_shared_secret, + uint8_t), + ret0); + memcpy(ret, ret0, (size_t)32U * sizeof(uint8_t)); +} + +/** + Portable decapsulate +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.kyber_decapsulate with const +generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CPA_SECRET_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- CIPHERTEXT_SIZE= 1088 +- T_AS_NTT_ENCODED_SIZE= 1152 +- C1_SIZE= 960 +- C2_SIZE= 128 +- VECTOR_U_COMPRESSION_FACTOR= 10 +- VECTOR_V_COMPRESSION_FACTOR= 4 +- C1_BLOCK_SIZE= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +- ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 +- IMPLICIT_REJECTION_HASH_INPUT_SIZE= 1120 +*/ +static inline void +libcrux_ml_kem_ind_cca_instantiations_portable_kyber_decapsulate_fc( + libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_ind_cca_decapsulate_700(private_key, ciphertext, ret); +} + +/** + Decapsulate Kyber 768 + + Generates an [`MlKemSharedSecret`]. + The input is a reference to an [`MlKem768PrivateKey`] and an + [`MlKem768Ciphertext`]. +*/ +static inline void libcrux_ml_kem_mlkem768_portable_kyber_decapsulate( + libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext, uint8_t ret[32U]) { + libcrux_ml_kem_ind_cca_instantiations_portable_kyber_decapsulate_fc( + private_key, ciphertext, ret); +} + +/** +This function found in impl {(libcrux_ml_kem::variant::Variant for +libcrux_ml_kem::variant::Kyber)} +*/ +/** +A monomorphic instance of libcrux_ml_kem.variant.entropy_preprocess_33 +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_variant_entropy_preprocess_33_8a( + Eurydice_slice randomness, uint8_t ret[32U]) { + libcrux_ml_kem_hash_functions_portable_H_f1_1a(randomness, ret); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.encapsulate +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_variant_Kyber with const generics +- K= 3 +- CIPHERTEXT_SIZE= 1088 +- PUBLIC_KEY_SIZE= 1184 +- T_AS_NTT_ENCODED_SIZE= 1152 +- C1_SIZE= 960 +- C2_SIZE= 128 +- VECTOR_U_COMPRESSION_FACTOR= 10 +- VECTOR_V_COMPRESSION_FACTOR= 4 +- VECTOR_U_BLOCK_LEN= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +- ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 +*/ +static inline tuple_3c libcrux_ml_kem_ind_cca_encapsulate_cd0( + libcrux_ml_kem_types_MlKemPublicKey_15 *public_key, + uint8_t randomness[32U]) { + uint8_t randomness0[32U]; + libcrux_ml_kem_variant_entropy_preprocess_33_8a( + Eurydice_array_to_slice((size_t)32U, randomness, uint8_t), randomness0); + uint8_t to_hash[64U]; + libcrux_ml_kem_utils_into_padded_array_ea( + Eurydice_array_to_slice((size_t)32U, randomness0, uint8_t), to_hash); + Eurydice_slice uu____0 = Eurydice_array_to_subslice_from( + (size_t)64U, to_hash, LIBCRUX_ML_KEM_CONSTANTS_H_DIGEST_SIZE, uint8_t, + size_t); + uint8_t ret[32U]; + libcrux_ml_kem_hash_functions_portable_H_f1_1a( + Eurydice_array_to_slice((size_t)1184U, + libcrux_ml_kem_types_as_slice_cb_50(public_key), + uint8_t), + ret); + Eurydice_slice_copy( + uu____0, Eurydice_array_to_slice((size_t)32U, ret, uint8_t), uint8_t); + uint8_t hashed[64U]; + libcrux_ml_kem_hash_functions_portable_G_f1_e4( + Eurydice_array_to_slice((size_t)64U, to_hash, uint8_t), hashed); + Eurydice_slice_uint8_t_x2 uu____1 = Eurydice_slice_split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), + LIBCRUX_ML_KEM_CONSTANTS_SHARED_SECRET_SIZE, uint8_t, + Eurydice_slice_uint8_t_x2); + Eurydice_slice shared_secret = uu____1.fst; + Eurydice_slice pseudorandomness = uu____1.snd; + Eurydice_slice uu____2 = Eurydice_array_to_slice( + (size_t)1184U, libcrux_ml_kem_types_as_slice_cb_50(public_key), uint8_t); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness[32U]; + memcpy(copy_of_randomness, randomness0, (size_t)32U * sizeof(uint8_t)); + uint8_t ciphertext[1088U]; + libcrux_ml_kem_ind_cpa_encrypt_60(uu____2, copy_of_randomness, + pseudorandomness, ciphertext); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_ciphertext[1088U]; + memcpy(copy_of_ciphertext, ciphertext, (size_t)1088U * sizeof(uint8_t)); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext ciphertext0 = + libcrux_ml_kem_types_from_01_9f(copy_of_ciphertext); + uint8_t shared_secret_array[32U]; + libcrux_ml_kem_variant_kdf_33_f0(shared_secret, &ciphertext0, + shared_secret_array); + libcrux_ml_kem_mlkem768_MlKem768Ciphertext uu____5 = ciphertext0; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_shared_secret_array[32U]; + memcpy(copy_of_shared_secret_array, shared_secret_array, + (size_t)32U * sizeof(uint8_t)); + tuple_3c lit; + lit.fst = uu____5; + memcpy(lit.snd, copy_of_shared_secret_array, (size_t)32U * sizeof(uint8_t)); + return lit; +} + +/** + Portable encapsulate +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.kyber_encapsulate with const +generics +- K= 3 +- CIPHERTEXT_SIZE= 1088 +- PUBLIC_KEY_SIZE= 1184 +- T_AS_NTT_ENCODED_SIZE= 1152 +- C1_SIZE= 960 +- C2_SIZE= 128 +- VECTOR_U_COMPRESSION_FACTOR= 10 +- VECTOR_V_COMPRESSION_FACTOR= 4 +- VECTOR_U_BLOCK_LEN= 320 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +- ETA2= 2 +- ETA2_RANDOMNESS_SIZE= 128 +*/ +static inline tuple_3c +libcrux_ml_kem_ind_cca_instantiations_portable_kyber_encapsulate_7a( + libcrux_ml_kem_types_MlKemPublicKey_15 *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey_15 *uu____0 = public_key; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness[32U]; + memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_encapsulate_cd0(uu____0, copy_of_randomness); +} + +/** + Encapsulate Kyber 768 + + Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. + The input is a reference to an [`MlKem768PublicKey`] and [`SHARED_SECRET_SIZE`] + bytes of `randomness`. +*/ +static inline tuple_3c libcrux_ml_kem_mlkem768_portable_kyber_encapsulate( + libcrux_ml_kem_types_MlKemPublicKey_15 *public_key, + uint8_t randomness[32U]) { + libcrux_ml_kem_types_MlKemPublicKey_15 *uu____0 = public_key; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness[32U]; + memcpy(copy_of_randomness, randomness, (size_t)32U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_kyber_encapsulate_7a( + uu____0, copy_of_randomness); +} + +/** +This function found in impl {(libcrux_ml_kem::variant::Variant for +libcrux_ml_kem::variant::Kyber)} +*/ +/** +A monomorphic instance of libcrux_ml_kem.variant.cpa_keygen_seed_33 +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +*/ +static KRML_MUSTINLINE void libcrux_ml_kem_variant_cpa_keygen_seed_33_b6( + Eurydice_slice key_generation_seed, uint8_t ret[64U]) { + libcrux_ml_kem_hash_functions_portable_G_f1_e4(key_generation_seed, ret); +} + +/** +A monomorphic instance of libcrux_ml_kem.ind_cpa.generate_keypair +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_variant_Kyber with const generics +- K= 3 +- PRIVATE_KEY_SIZE= 1152 +- PUBLIC_KEY_SIZE= 1184 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static inline libcrux_ml_kem_utils_extraction_helper_Keypair768 +libcrux_ml_kem_ind_cpa_generate_keypair_fc0( + Eurydice_slice key_generation_seed) { + uint8_t hashed[64U]; + libcrux_ml_kem_variant_cpa_keygen_seed_33_b6(key_generation_seed, hashed); + Eurydice_slice_uint8_t_x2 uu____0 = Eurydice_slice_split_at( + Eurydice_array_to_slice((size_t)64U, hashed, uint8_t), (size_t)32U, + uint8_t, Eurydice_slice_uint8_t_x2); + Eurydice_slice seed_for_A0 = uu____0.fst; + Eurydice_slice seed_for_secret_and_error = uu____0.snd; + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 A_transpose[3U][3U]; + uint8_t ret[34U]; + libcrux_ml_kem_utils_into_padded_array_ea1(seed_for_A0, ret); + libcrux_ml_kem_matrix_sample_matrix_A_38(ret, true, A_transpose); + uint8_t prf_input[33U]; + libcrux_ml_kem_utils_into_padded_array_ea2(seed_for_secret_and_error, + prf_input); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_prf_input0[33U]; + memcpy(copy_of_prf_input0, prf_input, (size_t)33U * sizeof(uint8_t)); + tuple_b0 uu____2 = libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc( + copy_of_prf_input0, 0U); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 secret_as_ntt[3U]; + memcpy( + secret_as_ntt, uu____2.fst, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + uint8_t domain_separator = uu____2.snd; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_prf_input[33U]; + memcpy(copy_of_prf_input, prf_input, (size_t)33U * sizeof(uint8_t)); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 error_as_ntt[3U]; + memcpy( + error_as_ntt, + libcrux_ml_kem_ind_cpa_sample_vector_cbd_then_ntt_fc(copy_of_prf_input, + domain_separator) + .fst, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 t_as_ntt[3U]; + libcrux_ml_kem_matrix_compute_As_plus_e_60(A_transpose, secret_as_ntt, + error_as_ntt, t_as_ntt); + uint8_t seed_for_A[32U]; + Result_00 dst; + Eurydice_slice_to_array2(&dst, seed_for_A0, Eurydice_slice, uint8_t[32U]); + unwrap_41_83(dst, seed_for_A); + uint8_t public_key_serialized[1184U]; + libcrux_ml_kem_ind_cpa_serialize_public_key_79( + t_as_ntt, Eurydice_array_to_slice((size_t)32U, seed_for_A, uint8_t), + public_key_serialized); + uint8_t secret_key_serialized[1152U]; + libcrux_ml_kem_ind_cpa_serialize_secret_key_b5(secret_as_ntt, + secret_key_serialized); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_secret_key_serialized[1152U]; + memcpy(copy_of_secret_key_serialized, secret_key_serialized, + (size_t)1152U * sizeof(uint8_t)); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_public_key_serialized[1184U]; + memcpy(copy_of_public_key_serialized, public_key_serialized, + (size_t)1184U * sizeof(uint8_t)); + libcrux_ml_kem_utils_extraction_helper_Keypair768 lit; + memcpy(lit.fst, copy_of_secret_key_serialized, + (size_t)1152U * sizeof(uint8_t)); + memcpy(lit.snd, copy_of_public_key_serialized, + (size_t)1184U * sizeof(uint8_t)); + return lit; +} + +/** + Packed API + + Generate a key pair. + + Depending on the `Vector` and `Hasher` used, this requires different hardware + features +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.generate_keypair +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector, +libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]], +libcrux_ml_kem_variant_Kyber with const generics +- K= 3 +- CPA_PRIVATE_KEY_SIZE= 1152 +- PRIVATE_KEY_SIZE= 2400 +- PUBLIC_KEY_SIZE= 1184 +- BYTES_PER_RING_ELEMENT= 1152 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_generate_keypair_8c0(uint8_t randomness[64U]) { + Eurydice_slice ind_cpa_keypair_randomness = Eurydice_array_to_subslice2( + randomness, (size_t)0U, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t); + Eurydice_slice implicit_rejection_value = Eurydice_array_to_subslice_from( + (size_t)64U, randomness, + LIBCRUX_ML_KEM_CONSTANTS_CPA_PKE_KEY_GENERATION_SEED_SIZE, uint8_t, + size_t); + libcrux_ml_kem_utils_extraction_helper_Keypair768 uu____0 = + libcrux_ml_kem_ind_cpa_generate_keypair_fc0(ind_cpa_keypair_randomness); + uint8_t ind_cpa_private_key[1152U]; + memcpy(ind_cpa_private_key, uu____0.fst, (size_t)1152U * sizeof(uint8_t)); + uint8_t public_key[1184U]; + memcpy(public_key, uu____0.snd, (size_t)1184U * sizeof(uint8_t)); + uint8_t secret_key_serialized[2400U]; + libcrux_ml_kem_ind_cca_serialize_kem_secret_key_48( + Eurydice_array_to_slice((size_t)1152U, ind_cpa_private_key, uint8_t), + Eurydice_array_to_slice((size_t)1184U, public_key, uint8_t), + implicit_rejection_value, secret_key_serialized); + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_secret_key_serialized[2400U]; + memcpy(copy_of_secret_key_serialized, secret_key_serialized, + (size_t)2400U * sizeof(uint8_t)); + libcrux_ml_kem_types_MlKemPrivateKey_55 private_key = + libcrux_ml_kem_types_from_05_f2(copy_of_secret_key_serialized); + libcrux_ml_kem_types_MlKemPrivateKey_55 uu____2 = private_key; + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_public_key[1184U]; + memcpy(copy_of_public_key, public_key, (size_t)1184U * sizeof(uint8_t)); + return libcrux_ml_kem_types_from_17_35( + uu____2, libcrux_ml_kem_types_from_b6_da(copy_of_public_key)); +} + +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.kyber_generate_keypair with const +generics +- K= 3 +- CPA_PRIVATE_KEY_SIZE= 1152 +- PRIVATE_KEY_SIZE= 2400 +- PUBLIC_KEY_SIZE= 1184 +- BYTES_PER_RING_ELEMENT= 1152 +- ETA1= 2 +- ETA1_RANDOMNESS_SIZE= 128 +*/ +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_ind_cca_instantiations_portable_kyber_generate_keypair_9b( + uint8_t randomness[64U]) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness[64U]; + memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_generate_keypair_8c0(copy_of_randomness); +} + +/** + Generate Kyber 768 Key Pair +*/ +static inline libcrux_ml_kem_mlkem768_MlKem768KeyPair +libcrux_ml_kem_mlkem768_portable_kyber_generate_key_pair( + uint8_t randomness[64U]) { + /* Passing arrays by value in Rust generates a copy in C */ + uint8_t copy_of_randomness[64U]; + memcpy(copy_of_randomness, randomness, (size_t)64U * sizeof(uint8_t)); + return libcrux_ml_kem_ind_cca_instantiations_portable_kyber_generate_keypair_9b( + copy_of_randomness); +} + +/** + Validate an ML-KEM private key. + + This implements the Hash check in 7.3 3. + Note that the size checks in 7.2 1 and 2 are covered by the `SECRET_KEY_SIZE` + and `CIPHERTEXT_SIZE` in the `private_key` and `ciphertext` types. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_private_key +with types libcrux_ml_kem_hash_functions_portable_PortableHash[[$3size_t]] +with const generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CIPHERTEXT_SIZE= 1088 +*/ +static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_private_key_e7( + libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *_ciphertext) { + uint8_t t[32U]; + libcrux_ml_kem_hash_functions_portable_H_f1_1a( + Eurydice_array_to_subslice2(private_key->value, (size_t)384U * (size_t)3U, + (size_t)768U * (size_t)3U + (size_t)32U, + uint8_t), + t); + Eurydice_slice expected = Eurydice_array_to_subslice2( + private_key->value, (size_t)768U * (size_t)3U + (size_t)32U, + (size_t)768U * (size_t)3U + (size_t)64U, uint8_t); + return core_array_equality___core__cmp__PartialEq__0___Slice_U____for__Array_T__N___3__eq( + (size_t)32U, t, &expected, uint8_t, uint8_t, bool); +} + +/** + Portable private key validation +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.validate_private_key with const +generics +- K= 3 +- SECRET_KEY_SIZE= 2400 +- CIPHERTEXT_SIZE= 1088 +*/ +static KRML_MUSTINLINE bool +libcrux_ml_kem_ind_cca_instantiations_portable_validate_private_key_9c( + libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext) { + return libcrux_ml_kem_ind_cca_validate_private_key_e7(private_key, + ciphertext); +} + +/** + Validate a private key. + + Returns `true` if valid, and `false` otherwise. +*/ +static inline bool libcrux_ml_kem_mlkem768_portable_validate_private_key( + libcrux_ml_kem_types_MlKemPrivateKey_55 *private_key, + libcrux_ml_kem_mlkem768_MlKem768Ciphertext *ciphertext) { + return libcrux_ml_kem_ind_cca_instantiations_portable_validate_private_key_9c( + private_key, ciphertext); +} + +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_ring_elements_reduced.closure with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- PUBLIC_KEY_SIZE= 1184 +- K= 3 +*/ +static inline libcrux_ml_kem_polynomial_PolynomialRingElement_f0 +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_closure_cd0( + size_t _i) { + return libcrux_ml_kem_polynomial_ZERO_89_ea(); +} + +/** + This function deserializes ring elements and reduces the result by the field + modulus. + + This function MUST NOT be used on secret inputs. +*/ +/** +A monomorphic instance of +libcrux_ml_kem.serialize.deserialize_ring_elements_reduced with types +libcrux_ml_kem_vector_portable_vector_type_PortableVector with const generics +- PUBLIC_KEY_SIZE= 1184 +- K= 3 +*/ +static KRML_MUSTINLINE void +libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_330( + Eurydice_slice public_key, + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 ret[3U]) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[3U]; + for (size_t i = (size_t)0U; i < (size_t)3U; i++) { + deserialized_pk[i] = libcrux_ml_kem_polynomial_ZERO_89_ea(); + } + for (size_t i = (size_t)0U; + i < Eurydice_slice_len(public_key, uint8_t) / + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT; + i++) { + size_t i0 = i; + Eurydice_slice ring_element = Eurydice_slice_subslice2( + public_key, i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + i0 * LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT + + LIBCRUX_ML_KEM_CONSTANTS_BYTES_PER_RING_ELEMENT, + uint8_t); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 uu____0 = + libcrux_ml_kem_serialize_deserialize_to_reduced_ring_element_4c( + ring_element); + deserialized_pk[i0] = uu____0; + } + memcpy( + ret, deserialized_pk, + (size_t)3U * sizeof(libcrux_ml_kem_polynomial_PolynomialRingElement_f0)); +} + +/** + Validate an ML-KEM public key. + + This implements the Modulus check in 7.2 2. + Note that the size check in 7.2 1 is covered by the `PUBLIC_KEY_SIZE` in the + `public_key` type. +*/ +/** +A monomorphic instance of libcrux_ml_kem.ind_cca.validate_public_key +with types libcrux_ml_kem_vector_portable_vector_type_PortableVector +with const generics +- K= 3 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +static KRML_MUSTINLINE bool libcrux_ml_kem_ind_cca_validate_public_key_19( + uint8_t *public_key) { + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 deserialized_pk[3U]; + libcrux_ml_kem_serialize_deserialize_ring_elements_reduced_330( + Eurydice_array_to_subslice_to((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t), + deserialized_pk); + libcrux_ml_kem_polynomial_PolynomialRingElement_f0 *uu____0 = deserialized_pk; + uint8_t public_key_serialized[1184U]; + libcrux_ml_kem_ind_cpa_serialize_public_key_79( + uu____0, + Eurydice_array_to_subslice_from((size_t)1184U, public_key, (size_t)1152U, + uint8_t, size_t), + public_key_serialized); + return core_array_equality___core__cmp__PartialEq__Array_U__N___for__Array_T__N____eq( + (size_t)1184U, public_key, public_key_serialized, uint8_t, uint8_t, bool); +} + +/** + Portable public key validation +*/ +/** +A monomorphic instance of +libcrux_ml_kem.ind_cca.instantiations.portable.validate_public_key with const +generics +- K= 3 +- RANKED_BYTES_PER_RING_ELEMENT= 1152 +- PUBLIC_KEY_SIZE= 1184 +*/ +static KRML_MUSTINLINE bool +libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key_4b( + uint8_t *public_key) { + return libcrux_ml_kem_ind_cca_validate_public_key_19(public_key); +} + +/** + Validate a public key. + + Returns `true` if valid, and `false` otherwise. +*/ +static inline bool libcrux_ml_kem_mlkem768_portable_validate_public_key( + libcrux_ml_kem_types_MlKemPublicKey_15 *public_key) { + return libcrux_ml_kem_ind_cca_instantiations_portable_validate_public_key_4b( + public_key->value); +} + +/** +This function found in impl {(core::clone::Clone for +libcrux_ml_kem::vector::portable::vector_type::PortableVector)} +*/ +static inline libcrux_ml_kem_vector_portable_vector_type_PortableVector +libcrux_ml_kem_vector_portable_vector_type_clone_3b( + libcrux_ml_kem_vector_portable_vector_type_PortableVector *self) { + return self[0U]; +} + +typedef int16_t libcrux_ml_kem_vector_portable_vector_type_FieldElement; + +typedef int16_t + libcrux_ml_kem_vector_portable_arithmetic_MontgomeryFieldElement; + +typedef int16_t + libcrux_ml_kem_vector_portable_arithmetic_FieldElementTimesMontgomeryR; + +#if defined(__cplusplus) +} +#endif + +#define __libcrux_mlkem768_portable_H_DEFINED +#endif + + +/* rename some types to be a bit more ergonomic */ +#define libcrux_mlkem768_keypair libcrux_ml_kem_mlkem768_MlKem768KeyPair_s +#define libcrux_mlkem768_pk_valid_result Option_92_s +#define libcrux_mlkem768_pk libcrux_ml_kem_types_MlKemPublicKey_15_s +#define libcrux_mlkem768_sk libcrux_ml_kem_types_MlKemPrivateKey_55_s +#define libcrux_mlkem768_ciphertext libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s +#define libcrux_mlkem768_enc_result tuple_3c_s +/* defines for PRNG inputs */ +#define LIBCRUX_ML_KEM_KEY_PAIR_PRNG_LEN 64 +#define LIBCRUX_ML_KEM_ENC_PRNG_LEN 32 diff --git a/log.c b/log.c index 619334a1023..0259f3f1efd 100644 --- a/log.c +++ b/log.c @@ -1,4 +1,4 @@ -/* $OpenBSD: log.c,v 1.62 2024/06/27 22:36:44 djm Exp $ */ +/* $OpenBSD: log.c,v 1.64 2024/12/07 10:05:36 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -38,14 +38,16 @@ #include +#include #include +#include #include #include #include #include #include +#include #include -#include #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) # include #endif @@ -469,9 +471,9 @@ sshlogv(const char *file, const char *func, int line, int showfunc, if (nlog_verbose == 0 && level > log_level) return; - snprintf(tag, sizeof(tag), "%.48s:%.48s():%d (pid=%ld)", + snprintf(tag, sizeof(tag), "%.48s:%.48s():%d (bin=%s, pid=%ld)", (cp = strrchr(file, '/')) == NULL ? file : cp + 1, func, line, - (long)getpid()); + argv0 == NULL ? "UNKNOWN" : argv0, (long)getpid()); for (i = 0; i < nlog_verbose; i++) { if (match_pattern_list(tag, log_verbose[i], 0) == 1) { forced = 1; @@ -498,3 +500,167 @@ sshlogdirect(LogLevel level, int forced, const char *fmt, ...) do_log(level, forced, NULL, fmt, args); va_end(args); } + + +/* + * A simple system for ratelimiting aperiodic events such as logs, without + * needing to be hooked into a mainloop/timer. A running total of events is + * maintained and when it exceeds a threshold further events are dropped + * until the rate falls back below that threshold. + * + * To prevent flipping in and out of rate-limiting, there is a hysteresis + * timer that delays leaving the rate-limited state. + * + * While in the rate-limited state, events can be periodically allowed though + * and the number of dropped events since the last log obtained. + * + * XXX a moving average rate of events might be a better approach here rather + * than linear decay, which can suppress events for a while after large + * bursts. + */ + +/* #define RATELIMIT_DEBUG 1 */ + +#ifdef RATELIMIT_DEBUG +# define RLDBG(x) do { \ + printf("%s:%d %s: ", __FILE__, __LINE__, __func__); \ + printf x; \ + printf("\n"); \ + fflush(stdout); \ + } while (0) +#else +# define RLDBG(x) +#endif + +/* set up a ratelimit */ +void +log_ratelimit_init(struct log_ratelimit_ctx *rl, u_int threshold, + u_int max_accum, u_int hysteresis, u_int log_every) +{ + memset(rl, 0, sizeof(*rl)); + rl->threshold = threshold; + rl->max_accum = max_accum; + rl->hysteresis = hysteresis; + rl->log_every = log_every; + RLDBG(("called: rl=%p thresh=%u max=%u hys=%u log_every=%u", + rl, rl->threshold, rl->max_accum, rl->hysteresis, rl->log_every)); +} + +/* + * check whether a log event should be dropped because of rate-limiting. + * returns non-zero if the event should be dropped. If events_since_last + * is supplied then, for periodic logs, it will be set to the number of + * dropped events since the last message. + */ +int +log_ratelimit(struct log_ratelimit_ctx *rl, time_t now, int *active, + u_int *events_dropped) +{ + time_t olast_event; + + RLDBG(("called: rl=%p thresh=%u max=%u hys=%u log_every=%u " + "accum=%u since=%ld since_last=%u", rl, rl->threshold, + rl->max_accum, rl->hysteresis, + rl->log_every, rl->accumulated_events, + rl->last_event == 0 ? -1 : (long)(now - rl->last_event), + rl->ratelimited_events)); + + if (now < 0) + return 0; + if (events_dropped != NULL) + *events_dropped = 0; + if (active != NULL) + *active = rl->ratelimit_active; + + /* First, decay accumulated events */ + if (rl->last_event <= 0) + rl->last_event = now; + if (now > rl->last_event) { + uint64_t n = now - rl->last_event; + + if (n > UINT_MAX) + n = UINT_MAX; + if (rl->accumulated_events < (u_int)n) + rl->accumulated_events = 0; + else + rl->accumulated_events -= (u_int)n; + RLDBG(("decay: accum=%u", rl->accumulated_events)); + } + rl->accumulated_events++; /* add this event */ + if (rl->accumulated_events > rl->max_accum) + rl->accumulated_events = rl->max_accum; + olast_event = rl->last_event; + rl->last_event = now; + RLDBG(("check threshold: accum=%u vs thresh=%u", + rl->accumulated_events, rl->threshold)); + + /* Are we under threshold? */ + if (rl->accumulated_events < rl->threshold) { + if (!rl->ratelimit_active) + return 0; + RLDBG(("under threshold: hys=%u since_hys=%ld since_last=%ld", + rl->hysteresis, rl->hysteresis_start == 0 ? -1 : + (long)(now - rl->hysteresis_start), + olast_event == 0 ? -1 : (long)(now - olast_event))); + if (rl->hysteresis_start == 0) { + /* active, but under threshold; hysteresis */ + if (olast_event + rl->hysteresis < now) { + /* hysteresis expired before this event */ + RLDBG(("hysteresis preexpired")); + goto inactive; + } + RLDBG(("start hysteresis")); + rl->hysteresis_start = now; + } else if (rl->hysteresis_start + rl->hysteresis < now) { + /* Hysteresis period expired, transition to inactive */ + RLDBG(("complete hysteresis")); + inactive: + if (events_dropped != NULL) + *events_dropped = rl->ratelimited_events; + if (active != NULL) + *active = 0; + rl->ratelimit_active = 0; + rl->ratelimit_start = 0; + rl->last_log = 0; + rl->hysteresis_start = 0; + rl->ratelimited_events = 0; + return 0; + } + /* ratelimiting active, but in hysteresis period */ + } else if (!rl->ratelimit_active) { + /* Transition to rate-limiting */ + RLDBG(("start ratelimit")); + rl->ratelimit_active = 1; + rl->ratelimit_start = now; + rl->last_log = now; + rl->hysteresis_start = 0; + rl->ratelimited_events = 1; + if (active != NULL) + *active = 1; + return 1; + } else if (rl->hysteresis_start != 0) { + /* active and over threshold; reset hysteresis timer */ + RLDBG(("clear hysteresis")); + rl->hysteresis_start = 0; + } + + /* over threshold or in hysteresis period; log periodically */ + if (active != NULL) + *active = 1; + RLDBG(("log_every=%u since_log=%ld", rl->log_every, + (long)(now - rl->last_log))); + if (rl->log_every > 0 && now >= rl->last_log + rl->log_every) { + RLDBG(("periodic: since_last=%u", rl->ratelimited_events)); + rl->last_log = now; + if (events_dropped != NULL) { + *events_dropped = rl->ratelimited_events; + rl->ratelimited_events = 0; + } + return 0; + } + + /* drop event */ + rl->ratelimited_events++; + RLDBG(("drop: ratelimited_events=%u", rl->ratelimited_events)); + return 1; +} diff --git a/log.h b/log.h index 8fe350b76d6..502372e64af 100644 --- a/log.h +++ b/log.h @@ -1,4 +1,4 @@ -/* $OpenBSD: log.h,v 1.34 2024/06/27 22:36:44 djm Exp $ */ +/* $OpenBSD: log.h,v 1.35 2024/12/07 10:05:37 djm Exp $ */ /* * Author: Tatu Ylonen @@ -81,6 +81,34 @@ void sshfatal(const char *, const char *, int, int, void sshlogdirect(LogLevel, int, const char *, ...) __attribute__((format(printf, 3, 4))); +#ifdef WINDOWS +typedef unsigned int u_int; +#endif /* WINDOWS */ + +struct log_ratelimit_ctx { + /* configuration */ + u_int threshold; /* events per second */ + u_int max_accum; /* max events to accumulate */ + u_int hysteresis; /* seconds */ + u_int log_every; /* seconds */ + + /* state */ + time_t last_event; + u_int accumulated_events; /* used for threshold comparisons */ + + /* state while actively rate-limiting */ + int ratelimit_active; + time_t ratelimit_start; + time_t last_log; + time_t hysteresis_start; + u_int ratelimited_events; +}; + +void log_ratelimit_init(struct log_ratelimit_ctx *rl, u_int threshold, + u_int max_accum, u_int hysteresis, u_int log_every); +int log_ratelimit(struct log_ratelimit_ctx *rl, time_t now, int *active, + u_int *events_dropped); + #define do_log2(level, ...) sshlog(__FILE__, __func__, __LINE__, 0, level, NULL, __VA_ARGS__) #define debug3(...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_DEBUG3, NULL, __VA_ARGS__) #define debug2(...) sshlog(__FILE__, __func__, __LINE__, 0, SYSLOG_LEVEL_DEBUG2, NULL, __VA_ARGS__) diff --git a/loginrec.c b/loginrec.c index 4f21499586a..c4a9bd4853e 100644 --- a/loginrec.c +++ b/loginrec.c @@ -25,27 +25,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * The btmp logging code is derived from login.c from util-linux and is under - * the the following license: - * - * Copyright (c) 1980, 1987, 1988 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - - /** ** loginrec.c: platform-independent login recording and lastlog retrieval **/ @@ -187,6 +166,10 @@ # include #endif +#ifdef USE_WTMPDB +# include +#endif + /** ** prototypes for helper functions in this file **/ @@ -207,6 +190,9 @@ int wtmp_write_entry(struct logininfo *li); int wtmpx_write_entry(struct logininfo *li); int lastlog_write_entry(struct logininfo *li); int syslogin_write_entry(struct logininfo *li); +#ifdef USE_WTMPDB +int wtmpdb_write_entry(struct logininfo *li); +#endif int getlast_entry(struct logininfo *li); int lastlog_get_entry(struct logininfo *li); @@ -467,6 +453,9 @@ login_write(struct logininfo *li) #ifdef USE_WTMPX wtmpx_write_entry(li); #endif +#ifdef USE_WTMPDB + wtmpdb_write_entry(li); +#endif #ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN if (li->type == LTYPE_LOGIN && !sys_auth_record_login(li->username,li->hostname,li->line, @@ -603,6 +592,9 @@ line_abbrevname(char *dst, const char *src, int dstsize) memset(dst, '\0', dstsize); + if (strcmp(src, "ssh:notty") == 0) + return dst; + /* Always skip prefix if present */ if (strncmp(src, "/dev/", 5) == 0) src += 5; @@ -632,7 +624,7 @@ line_abbrevname(char *dst, const char *src, int dstsize) ** into account. **/ -#if defined(USE_UTMP) || defined (USE_WTMP) || defined (USE_LOGIN) +#if defined(USE_BTMP) || defined(USE_UTMP) || defined (USE_WTMP) || defined (USE_LOGIN) /* build the utmp structure */ void @@ -716,7 +708,7 @@ construct_utmp(struct logininfo *li, } # endif } -#endif /* USE_UTMP || USE_WTMP || USE_LOGIN */ +#endif /* USE_BTMP || USE_UTMP || USE_WTMP || USE_LOGIN */ /** ** utmpx utility functions @@ -741,7 +733,7 @@ set_utmpx_time(struct logininfo *li, struct utmpx *utx) void construct_utmpx(struct logininfo *li, struct utmpx *utx) { -# ifdef HAVE_ADDR_V6_IN_UTMP +# ifdef HAVE_ADDR_V6_IN_UTMPX struct sockaddr_in6 *sa6; # endif memset(utx, '\0', sizeof(*utx)); @@ -787,7 +779,7 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) if (li->hostaddr.sa.sa_family == AF_INET) utx->ut_addr = li->hostaddr.sa_in.sin_addr.s_addr; # endif -# ifdef HAVE_ADDR_V6_IN_UTMP +# ifdef HAVE_ADDR_V6_IN_UTMPX /* this is just a 128-bit IPv6 address */ if (li->hostaddr.sa.sa_family == AF_INET6) { sa6 = ((struct sockaddr_in6 *)&li->hostaddr.sa); @@ -1033,7 +1025,7 @@ utmpx_perform_login(struct logininfo *li) return (0); } # else - if (!utmpx_write_direct(li, &ut)) { + if (!utmpx_write_direct(li, &utx)) { logit("%s: utmp_write_direct() failed", __func__); return (0); } @@ -1409,6 +1401,64 @@ wtmpx_get_entry(struct logininfo *li) } #endif /* USE_WTMPX */ +#ifdef USE_WTMPDB +static int +wtmpdb_perform_login(struct logininfo *li) +{ + uint64_t login_time = li->tv_sec * ((uint64_t) 1000000ULL) + + li->tv_usec; + const char *tty; + + if (strncmp(li->line, "/dev/", 5) == 0) + tty = &(li->line[5]); + else + tty = li->line; + + li->wtmpdb_id = wtmpdb_login(NULL, USER_PROCESS, li->username, + login_time, tty, li->hostname, 0, 0); + + if (li->wtmpdb_id < 0) + return (0); + + return (1); +} + +static int +wtmpdb_perform_logout(struct logininfo *li) +{ + uint64_t logout_time = li->tv_sec * ((uint64_t) 1000000ULL) + + li->tv_usec; + + if (li->wtmpdb_id == 0) { + const char *tty; + + if (strncmp(li->line, "/dev/", 5) == 0) + tty = &(li->line[5]); + else + tty = li->line; + + li->wtmpdb_id = wtmpdb_get_id(NULL, tty, NULL); + } + wtmpdb_logout(NULL, li->wtmpdb_id, logout_time, NULL); + + return (1); +} + +int +wtmpdb_write_entry(struct logininfo *li) +{ + switch(li->type) { + case LTYPE_LOGIN: + return (wtmpdb_perform_login(li)); + case LTYPE_LOGOUT: + return (wtmpdb_perform_logout(li)); + default: + logit("%s: invalid type field", __func__); + return (0); + } +} +#endif + /** ** Low-level libutil login() functions **/ @@ -1547,10 +1597,10 @@ lastlog_write_entry(struct logininfo *li) strlcpy(last.ll_host, li->hostname, MIN_SIZEOF(last.ll_host, li->hostname)); last.ll_time = li->tv_sec; - + if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) return (0); - + /* write the entry */ if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { close(fd); @@ -1558,7 +1608,7 @@ lastlog_write_entry(struct logininfo *li) LASTLOG_FILE, strerror(errno)); return (0); } - + close(fd); return (1); default: @@ -1651,23 +1701,20 @@ utmpx_get_entry(struct logininfo *li) #endif /* USE_UTMPX && HAVE_SETUTXDB && UTXDB_LASTLOGIN && HAVE_GETUTXUSER */ #ifdef USE_BTMP - /* - * Logs failed login attempts in _PATH_BTMP if that exists. - * The most common login failure is to give password instead of username. - * So the _PATH_BTMP file checked for the correct permission, so that - * only root can read it. - */ - +/* + * Logs failed login attempts in _PATH_BTMP if that exists. + * The most common login failure is to give password instead of username. + * So the _PATH_BTMP file checked for the correct permission, so that only + * root can read it. + */ void record_failed_login(struct ssh *ssh, const char *username, const char *hostname, const char *ttyn) { int fd; struct utmp ut; - struct sockaddr_storage from; - socklen_t fromlen = sizeof(from); - struct sockaddr_in *a4; - struct sockaddr_in6 *a6; + struct logininfo li; + socklen_t fromlen = sizeof(li.hostaddr); time_t t; struct stat fst; @@ -1683,47 +1730,31 @@ record_failed_login(struct ssh *ssh, const char *username, const char *hostname, strerror(errno)); goto out; } - if((fst.st_mode & (S_IXGRP | S_IRWXO)) || (fst.st_uid != 0)){ + if ((fst.st_mode & (S_IXGRP | S_IRWXO)) || fst.st_uid != 0) { logit("Excess permission or bad ownership on file %s", _PATH_BTMP); goto out; } - memset(&ut, 0, sizeof(ut)); - /* strncpy because we don't necessarily want nul termination */ - strncpy(ut.ut_user, username, sizeof(ut.ut_user)); - strlcpy(ut.ut_line, "ssh:notty", sizeof(ut.ut_line)); - + /* Construct a logininfo and turn it into a utmp */ + memset(&li, 0, sizeof(li)); + li.type = LTYPE_LOGIN; + li.pid = getpid(); + strlcpy(li.line, "ssh:notty", sizeof(li.line)); + strlcpy(li.username, username, sizeof(li.username)); + strlcpy(li.hostname, hostname, sizeof(li.hostname)); time(&t); - ut.ut_time = t; /* ut_time is not always a time_t */ - ut.ut_type = LOGIN_PROCESS; - ut.ut_pid = getpid(); - - /* strncpy because we don't necessarily want nul termination */ - strncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); - - if (ssh_packet_connection_is_on_socket(ssh) && - getpeername(ssh_packet_get_connection_in(ssh), - (struct sockaddr *)&from, &fromlen) == 0) { - ipv64_normalise_mapped(&from, &fromlen); - if (from.ss_family == AF_INET) { - a4 = (struct sockaddr_in *)&from; - memcpy(&ut.ut_addr, &(a4->sin_addr), - MIN_SIZEOF(ut.ut_addr, a4->sin_addr)); - } -#ifdef HAVE_ADDR_V6_IN_UTMP - if (from.ss_family == AF_INET6) { - a6 = (struct sockaddr_in6 *)&from; - memcpy(&ut.ut_addr_v6, &(a6->sin6_addr), - MIN_SIZEOF(ut.ut_addr_v6, a6->sin6_addr)); - } -#endif + li.tv_sec = t > 0 ? (unsigned long)t : 0; + if (ssh_packet_connection_is_on_socket(ssh)) { + (void)getpeername(ssh_packet_get_connection_in(ssh), + &li.hostaddr.sa, &fromlen); } + construct_utmp(&li, &ut); - if (atomicio(vwrite, fd, &ut, sizeof(ut)) != sizeof(ut)) + if (atomicio(vwrite, fd, &ut, sizeof(ut)) != sizeof(ut)) { error("Failed to write to %s: %s", _PATH_BTMP, strerror(errno)); - + } out: close(fd); } diff --git a/loginrec.h b/loginrec.h index 02bceb604c7..62ddd01d515 100644 --- a/loginrec.h +++ b/loginrec.h @@ -79,6 +79,9 @@ struct logininfo { unsigned int tv_sec; unsigned int tv_usec; union login_netinfo hostaddr; /* caller's host address(es) */ +#ifdef USE_WTMPDB + int64_t wtmpdb_id; /* ID for wtmpdb_logout */ +#endif }; /* struct logininfo */ /* diff --git a/match.c b/match.c index 6f3e752b818..28ef55a0682 100644 --- a/match.c +++ b/match.c @@ -1,4 +1,4 @@ -/* $OpenBSD: match.c,v 1.44 2023/04/06 03:19:32 djm Exp $ */ +/* $OpenBSD: match.c,v 1.45 2024/09/06 02:30:44 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -249,7 +249,7 @@ match_user(const char *user, const char *host, const char *ipaddr, /* test mode */ if (user == NULL && host == NULL && ipaddr == NULL) { - if ((p = strchr(pattern, '@')) != NULL && + if ((p = strrchr(pattern, '@')) != NULL && match_host_and_ip(NULL, NULL, p + 1) < 0) return -1; return 0; @@ -258,11 +258,11 @@ match_user(const char *user, const char *host, const char *ipaddr, if (user == NULL) return 0; /* shouldn't happen */ - if ((p = strchr(pattern, '@')) == NULL) + if (strrchr(pattern, '@') == NULL) return match_pattern(user, pattern); pat = xstrdup(pattern); - p = strchr(pat, '@'); + p = strrchr(pat, '@'); *p++ = '\0'; if ((ret = match_pattern(user, pat)) == 1) diff --git a/mdoc2man.awk b/mdoc2man.awk index d393ae6f147..02a04f7621d 100644 --- a/mdoc2man.awk +++ b/mdoc2man.awk @@ -239,7 +239,7 @@ function add(str) { while(w") - if(option) + for(;option;option--) add("]") if(ext&&!extopt&&!match(line," $")) add(OFS) diff --git a/misc.c b/misc.c index 3d5709bd035..f8c8a7beac2 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.196 2024/06/06 17:15:25 djm Exp $ */ +/* $OpenBSD: misc.c,v 1.198 2024/10/24 03:14:37 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005-2020 Damien Miller. All rights reserved. @@ -109,6 +109,27 @@ rtrim(char *s) } } +/* + * returns pointer to character after 'prefix' in 's' or otherwise NULL + * if the prefix is not present. + */ +const char * +strprefix(const char *s, const char *prefix, int ignorecase) +{ + size_t prefixlen; + + if ((prefixlen = strlen(prefix)) == 0) + return s; + if (ignorecase) { + if (strncasecmp(s, prefix, prefixlen) != 0) + return NULL; + } else { + if (strncmp(s, prefix, prefixlen) != 0) + return NULL; + } + return s + prefixlen; +} + /* set/unset filedescriptor to non-blocking */ int set_nonblock(int fd) @@ -2474,7 +2495,8 @@ valid_domain(char *name, int makelower, const char **errstr) strlcpy(errbuf, "empty domain name", sizeof(errbuf)); goto bad; } - if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) { + if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0]) && + name[0] != '_' /* technically invalid, but common */) { snprintf(errbuf, sizeof(errbuf), "domain name \"%.100s\" " "starts with invalid character", name); goto bad; diff --git a/misc.h b/misc.h index 1b650866c96..ace2a2ffb72 100644 --- a/misc.h +++ b/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.109 2024/06/06 17:15:25 djm Exp $ */ +/* $OpenBSD: misc.h,v 1.110 2024/09/25 01:24:04 djm Exp $ */ /* * Author: Tatu Ylonen @@ -56,6 +56,7 @@ struct ForwardOptions { char *chop(char *); void rtrim(char *); void skip_space(char **); +const char *strprefix(const char *, const char *, int); char *strdelim(char **); char *strdelimw(char **); int set_nonblock(int); diff --git a/mlkem768.sh b/mlkem768.sh new file mode 100644 index 00000000000..cbc3d14da2e --- /dev/null +++ b/mlkem768.sh @@ -0,0 +1,163 @@ +#!/bin/sh +# $OpenBSD: mlkem768.sh,v 1.3 2024/10/27 02:06:01 djm Exp $ +# Placed in the Public Domain. +# + +#WANT_LIBCRUX_REVISION="origin/main" +WANT_LIBCRUX_REVISION="84c5d87b3092c59294345aa269ceefe0eb97cc35" + +FILES=" + libcrux/libcrux-ml-kem/cg/eurydice_glue.h + libcrux/libcrux-ml-kem/cg/libcrux_core.h + libcrux/libcrux-ml-kem/cg/libcrux_ct_ops.h + libcrux/libcrux-ml-kem/cg/libcrux_sha3_portable.h + libcrux/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h +" + +START="$PWD" +die() { + echo "$@" 1>&2 + exit 1 +} + +set -xeuo pipefail +test -d libcrux || git clone https://github.com/cryspen/libcrux +cd libcrux +test `git diff | wc -l` -ne 0 && die "tree has unstaged changes" +git fetch +git checkout -B extract 1>&2 +git reset --hard $WANT_LIBCRUX_REVISION 1>&2 +LIBCRUX_REVISION=`git rev-parse HEAD` +set +x + +cd $START +( +printf '/* $Open'; printf 'BSD$ */\n' # Sigh +echo +echo "/* Extracted from libcrux revision $LIBCRUX_REVISION */" +echo +echo '/*' +cat libcrux/LICENSE-MIT | sed 's/^/ * /;s/ *$//' +echo ' */' +echo +echo '#if !defined(__GNUC__) || (__GNUC__ < 2)' +echo '# define __attribute__(x)' +echo '#endif' +echo '#define KRML_MUSTINLINE inline' +echo '#define KRML_NOINLINE __attribute__((noinline, unused))' +echo '#define KRML_HOST_EPRINTF(...)' +echo '#define KRML_HOST_EXIT(x) fatal_f("internal error")' +echo + +__builtin_popcount_replacement=' + const uint8_t v[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + return v[x0 & 0xf] + v[(x0 >> 4) & 0xf]; +' + +for i in $FILES; do + echo "/* from $i */" + # Changes to all files: + # - remove all includes, we inline everything required. + # - cleanup whitespace + sed -e "/#include/d" \ + -e 's/[ ]*$//' \ + $i | \ + case "$i" in + */libcrux-ml-kem/cg/eurydice_glue.h) + # Replace endian functions with versions that work. + perl -0777 -pe 's/(static inline void core_num__u64_9__to_le_bytes.*\n)([^}]*\n)/\1 v = htole64(v);\n\2/' | + perl -0777 -pe 's/(static inline uint64_t core_num__u64_9__from_le_bytes.*?)return v;/\1return le64toh(v);/s' | + perl -0777 -pe 's/(static inline uint32_t core_num__u32_8__from_le_bytes.*?)return v;/\1return le32toh(v);/s' | + # Compat for popcount. + perl -0777 -pe 's/\#ifdef (_MSC_VER)(.*?return __popcnt\(x0\);)/\#if defined(\1)\2/s' | + perl -0777 -pe "s/\\#else(\\n\\s+return __builtin_popcount\\(x0\\);)/\\#elif !defined(MISSING_BUILTIN_POPCOUNT)\\1\\n#else$__builtin_popcount_replacement/s" + ;; + # Default: pass through. + *) + cat + ;; + esac + echo +done + +echo +echo '/* rename some types to be a bit more ergonomic */' +echo '#define libcrux_mlkem768_keypair libcrux_ml_kem_mlkem768_MlKem768KeyPair_s' +echo '#define libcrux_mlkem768_pk_valid_result Option_92_s' +echo '#define libcrux_mlkem768_pk libcrux_ml_kem_types_MlKemPublicKey_15_s' +echo '#define libcrux_mlkem768_sk libcrux_ml_kem_types_MlKemPrivateKey_55_s' +echo '#define libcrux_mlkem768_ciphertext libcrux_ml_kem_mlkem768_MlKem768Ciphertext_s' +echo '#define libcrux_mlkem768_enc_result tuple_3c_s' +) > libcrux_mlkem768_sha3.h_new + +# Do some checks on the resultant file + +cat > libcrux_mlkem768_sha3_check.c << _EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include "crypto_api.h" +#define fatal_f(x) exit(1) +#include "libcrux_mlkem768_sha3.h_new" +int main(void) { + struct libcrux_mlkem768_keypair keypair = {0}; + struct libcrux_mlkem768_pk pk = {0}; + struct libcrux_mlkem768_sk sk = {0}; + struct libcrux_mlkem768_ciphertext ct = {0}; + struct libcrux_mlkem768_enc_result enc_result = {0}; + uint8_t kp_seed[64] = {0}, enc_seed[32] = {0}; + uint8_t shared_key[crypto_kem_mlkem768_BYTES]; + + if (sizeof(keypair.pk.value) != crypto_kem_mlkem768_PUBLICKEYBYTES) + errx(1, "keypair.pk bad"); + if (sizeof(keypair.sk.value) != crypto_kem_mlkem768_SECRETKEYBYTES) + errx(1, "keypair.sk bad"); + if (sizeof(pk.value) != crypto_kem_mlkem768_PUBLICKEYBYTES) + errx(1, "pk bad"); + if (sizeof(sk.value) != crypto_kem_mlkem768_SECRETKEYBYTES) + errx(1, "sk bad"); + if (sizeof(ct.value) != crypto_kem_mlkem768_CIPHERTEXTBYTES) + errx(1, "ct bad"); + if (sizeof(enc_result.fst.value) != crypto_kem_mlkem768_CIPHERTEXTBYTES) + errx(1, "enc_result ct bad"); + if (sizeof(enc_result.snd) != crypto_kem_mlkem768_BYTES) + errx(1, "enc_result shared key bad"); + + keypair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(kp_seed); + if (!libcrux_ml_kem_mlkem768_portable_validate_public_key(&keypair.pk)) + errx(1, "valid smoke failed"); + enc_result = libcrux_ml_kem_mlkem768_portable_encapsulate(&keypair.pk, + enc_seed); + libcrux_ml_kem_mlkem768_portable_decapsulate(&keypair.sk, + &enc_result.fst, shared_key); + if (memcmp(shared_key, enc_result.snd, sizeof(shared_key)) != 0) + errx(1, "smoke failed"); + return 0; +} +_EOF +cc -Wall -Wextra -Wno-unused-parameter -o libcrux_mlkem768_sha3_check \ + libcrux_mlkem768_sha3_check.c +./libcrux_mlkem768_sha3_check + +# Extract PRNG inputs; there's no nice #defines for these +key_pair_rng_len=`sed -e '/^libcrux_ml_kem_mlkem768_portable_kyber_generate_key_pair[(]$/,/[)] {$/!d' < libcrux_mlkem768_sha3.h_new | grep 'uint8_t randomness\[[0-9]*U\][)]' | sed 's/.*randomness\[\([0-9]*\)U\].*/\1/'` +enc_rng_len=`sed -e '/^static inline tuple_3c libcrux_ml_kem_mlkem768_portable_kyber_encapsulate[(]$/,/[)] {$/!d' < libcrux_mlkem768_sha3.h_new | grep 'uint8_t randomness\[[0-9]*U\][)]' | sed 's/.*randomness\[\([0-9]*\)U\].*/\1/'` +test -z "$key_pair_rng_len" && die "couldn't find size of libcrux_ml_kem_mlkem768_portable_kyber_generate_key_pair randomness argument" +test -z "$enc_rng_len" && die "couldn't find size of libcrux_ml_kem_mlkem768_portable_kyber_encapsulate randomness argument" + +( +echo "/* defines for PRNG inputs */" +echo "#define LIBCRUX_ML_KEM_KEY_PAIR_PRNG_LEN $key_pair_rng_len" +echo "#define LIBCRUX_ML_KEM_ENC_PRNG_LEN $enc_rng_len" +) >> libcrux_mlkem768_sha3.h_new + +mv libcrux_mlkem768_sha3.h_new libcrux_mlkem768_sha3.h +rm libcrux_mlkem768_sha3_check libcrux_mlkem768_sha3_check.c +echo 1>&2 +echo "libcrux_mlkem768_sha3.h OK" 1>&2 + diff --git a/moduli b/moduli index fb682e45aad..ab7fd2bb0c2 100644 --- a/moduli +++ b/moduli @@ -1,469 +1,434 @@ -# $OpenBSD: moduli,v 1.37 2024/03/26 01:23:11 dtucker Exp $ +# $OpenBSD: moduli,v 1.39 2024/11/29 00:13:36 dtucker Exp $ # Time Type Tests Tries Size Generator Modulus -20240104095616 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E18168688F265F -20240104095622 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E1816868B9D16B -20240104095623 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E1816868BE5B5B -20240104095635 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E18168691008CB -20240104095636 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E1816869118D93 -20240104095705 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E1816869F03EDB -20240104095716 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686A45B59F -20240104095724 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686A76925B -20240104095725 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686A7CBA63 -20240104095735 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686AC16E5B -20240104095748 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686B23EC2F -20240104095803 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686B8C2C0B -20240104095812 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686BC90DD7 -20240104095816 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686BE3B4F7 -20240104095818 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686BEB2A0B -20240104095834 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686C601253 -20240104095837 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686C747FFB -20240104095900 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686D2720BF -20240104095904 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686D3E5603 -20240104095908 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686D5635F3 -20240104095917 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686D92F173 -20240104095918 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686D93EFD7 -20240104095920 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686D9E4673 -20240104095934 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686E020E77 -20240104095941 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686E319F3B -20240104095947 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686E5EC05F -20240104100001 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686EC17C4F -20240104100012 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686F12137F -20240104100026 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686F73FAC3 -20240104100029 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686F88A3FF -20240104100038 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686FC81D1F -20240104100039 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686FCD023B -20240104100042 2 6 100 2047 5 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181686FDA5E8F -20240104100056 2 6 100 2047 2 C383B937F2718D0CF93B36B8C4AA5B68E7B0E45E07100F8E40336B40B211BD1B4199CC92D5D03890022C8855239908B7348F8C76667368F8F73988568196B6308F9CCBB2571B9B88258C0DD717FB2ECB063B05BC2E36AE5EC2941E2D52133405B5DB9219C76B11764CAF1D73001036AB26ECE915DD4FE21251F01C19C415B0DA80231EE10410BEF198E0FE320E105844F537E2D6A45E77B0B16454931C30ED888D505641E5A4D07DD7937276ED988EB5DB7CC54C8CF5FF28FD39F4FBBC49AF7E023AE39396796A4736279495BC00EC89FE830A7C0BCDEFFDF910FD80F702078543CC2D1E53EB0F510EB9CBE78819B3E33BEA921612FCD755E4E181687044E3F3 -20240104100101 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB8C5E15E3 -20240104100123 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB8D074C03 -20240104100130 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB8D33D613 -20240104100141 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB8D811FD3 -20240104100145 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB8D99912B -20240104100202 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB8E169543 -20240104100223 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB8EB0BA6B -20240104100226 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB8EBF5F7B -20240104100227 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB8EC40C1B -20240104100242 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB8F2E1DF3 -20240104100245 2 6 100 2047 5 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB8F3C8C67 -20240104100254 2 6 100 2047 5 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB8F795C9F -20240104100317 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB902632A3 -20240104100332 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB9096384B -20240104100334 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB90A286C3 -20240104100336 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB90AA1ABB -20240104100338 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB90B5380B -20240104100344 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB90DAA413 -20240104100351 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB910CE893 -20240104100351 2 6 100 2047 5 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB910EBF0F -20240104100416 2 6 100 2047 5 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB91C2935F -20240104100422 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB91EE5C43 -20240104100433 2 6 100 2047 5 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB92428037 -20240104100436 2 6 100 2047 5 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB924F7E5F -20240104100448 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB92A78E33 -20240104100452 2 6 100 2047 5 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB92C39FFF -20240104100502 2 6 100 2047 5 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB930AB887 -20240104100511 2 6 100 2047 5 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB93484697 -20240104100513 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB934EE903 -20240104100521 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB93859FA3 -20240104100525 2 6 100 2047 5 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB93A15877 -20240104100532 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB93CEA42B -20240104100536 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB93F09E33 -20240104100547 2 6 100 2047 2 EDE2897770950A39DDAC39B88173C52469FCA04AAD0665C1C1FA7059B7859FD1F84ED9C9510F7ECAAD251C174DB09975EAE851EE71A9BD0F83F6E2022723E66ECDE73BFB6D940A1A1D6112197BC1DE040CDD9D3A80BDA683679CB0705FA548878C8720CB14BDAFFF61AE546A8450B000EAC1DB6756C04E7FF65D2131A1015F741396395858BA490C0A65920817F114BD74FCBF1019BFD5E3C31E49CE523818113DB2097DB3CBFF4F5D6F323F72A084C54CD042FC053D378F458CC55088D170BF36539FAD7A019AF20491C29A95FBF036C1D18B8035BB10ABB5321DDD1201DAF890AE31F3B77451C1A8A927AEBA77613E4EBBB490414B19451446A3BB943E537B -20240104101115 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A0D5ED5B -20240104101119 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A0DC38D3 -20240104101145 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A12CF7DB -20240104101213 2 6 100 3071 5 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A17CE1A7 -20240104101309 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A21EA1DB -20240104101404 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A2CFD013 -20240104101448 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A356C09B -20240104101513 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A3A06C1B -20240104101532 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A3DC6ACB -20240104101754 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A59D6073 -20240104101824 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A5F889D3 -20240104101914 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A69226F3 -20240104102026 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A7778413 -20240104102104 2 6 100 3071 5 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A7ED53AF -20240104102111 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A7FC79FB -20240104102143 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A85B8803 -20240104102252 2 6 100 3071 5 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A938656F -20240104102259 2 6 100 3071 5 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A9493BAF -20240104102310 2 6 100 3071 5 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53A967D647 -20240104102422 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AA47EBC3 -20240104102451 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AAA0B5EB -20240104102523 2 6 100 3071 5 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AB06D25F -20240104102545 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AB48A373 -20240104102701 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AC38C9B3 -20240104102738 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53ACA7A56B -20240104102808 2 6 100 3071 5 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AD033D5F -20240104102825 2 6 100 3071 5 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AD32BE27 -20240104102848 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AD75754B -20240104102913 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53ADBBC7BB -20240104102931 2 6 100 3071 5 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53ADF2C9AF -20240104102936 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53ADFA97A3 -20240104103004 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AE4E97A3 -20240104103054 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AEE6F5A3 -20240104103136 2 6 100 3071 5 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AF6C7D17 -20240104103155 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AFA24993 -20240104103204 2 6 100 3071 5 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AFBD89BF -20240104103225 2 6 100 3071 5 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53AFFADD37 -20240104103441 2 6 100 3071 2 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53B1BE6E0B -20240104103449 2 6 100 3071 5 E5200F78D0067C75B413BFE21DBBB301C8D14F8A46C0D16A957F5FD8708569CEFA51C549F9493C21ACE299A60AB6C8191EC47A356BBD2E41B9BDBC12486F1783F1FC3E559D29B4863898B5976E7108C391F1DD63B58F705109961D1577EDC807AFB96777476D1DD837AF21F81B6556EAB1BF0576552FF3304AABF72FFFC460E83982B3290C139E75D1628B2562B1A541D28551569C6336041CFCA45BAF9955EC7CE3364BBB9344C59BDFB346F1316F9D2538EDA32A6C4A018799ECB20FD383CC8191903B26FAE0F84FFF6FCB5E0D6CC50F25E7C2F4D05AC02BE22DF03781BDE9A5FC4951C4A20495E18B12111FCEB42F4B41CB9C6BE9E7FEBD2A224CFFB0028E2D22DA3A00CB48B2AFAB5287445B04ACFD65164EC97370FD89F2F04C2190D2AE9590CA2B88A4E946D1B62684D76AC39E291A201BF50BD9D521458AA9BA0F11416018F59D98DA058F5F4A67078AF968E51B193A74BE8486ABB1ACBD89A16D6F053B2FDB6D769195D2452E932719714E3474844AA606BD9D3186D4BB53B1D4228F -20240104103608 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F45F532253 -20240104103721 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46039F7FF -20240104103727 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46046CF03 -20240104103902 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F4616F9AE3 -20240104103918 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F4619C6F1B -20240104103932 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F461C2094F -20240104103959 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46210E24B -20240104104005 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F4621D6F93 -20240104104014 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F4623557F3 -20240104104041 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46283FC03 -20240104104104 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F462C76DF3 -20240104104124 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F463010D2F -20240104104145 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F4633D54E7 -20240104104221 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F463A5D183 -20240104104232 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F463C2FF47 -20240104104250 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F463F7D33B -20240104104437 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F4653512CF -20240104104548 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F4661420E7 -20240104104605 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F466462DDB -20240104104608 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F466482167 -20240104104613 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46651DF9F -20240104104619 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F4665D3CD3 -20240104104654 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F466C8206F -20240104104716 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46706CDFB -20240104104816 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F467C6AC6B -20240104104849 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F4682E9853 -20240104104939 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F468CD47B3 -20240104105103 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F469DC1C53 -20240104105116 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F469FD7CA7 -20240104105238 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46B04E72B -20240104105406 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46C1C8F1F -20240104105432 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46C69A60F -20240104105538 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46D3431C7 -20240104105600 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46D7551CF -20240104105623 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46DBA58FB -20240104105913 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46FDA4817 -20240104105921 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F46FEE672F -20240104105938 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F47022732B -20240104110025 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F470BAC72F -20240104110044 2 6 100 3071 5 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F470F2A087 -20240104110057 2 6 100 3071 2 EDCE3D686B1FF9B87585480575F96A54B973EBC8E9330E7CA890624CE60311FFB65EBFB08E9B6D6184895C6C78238241D12F50B9178DD3F77DEAABB0BDF084F9B7713B72CE5ABD25BAEECBFEC06957BC92D74EBC234D87B255ACD94372785BAAE5362EDD5E75D025FB7E4B36A9636A8F65141BDA5E5789F4C09E6FEEF47B2F56CBB05002856A2A85F3E25A83808E1AE44578ACA4A3139792B971D452CD2DFEE48A28C1CA7616E4E06218D0062EEDD5622D6F1B84DE03DBEA72F97A907F8CEFBB102C54657127F646A4B2422CE2503341B18E2E1424755628F11EB7B9D8938C939586E3CE84CD5620BD2AE105E7D821D97FC85B92F00A72DC47450C258143E1A5C99E4E89AC94E0BB028C650D10BB9EAB68C9EA5D7C3BB2D139590572A8421C3AE1B440DB320A99A439E542FB79754BAEE30361B8E8519FD118E60D33FDB1FC20FCE9A275CAEC3F4605DC8E1CBDBA207951BEFDE24227F34A9788EDBF91E9088A5255165F27AC8DF63FB4FDCEDB43FAD4D3E0606A0F27DD50C41BD5F47113FA93 -20240104111235 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92ED6D5283 -20240104111516 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92EE6BFE0B -20240104111802 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92EF69F083 -20240104111812 2 6 100 4095 5 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92EF7314EF -20240104112330 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F168359B -20240104112346 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F17A8473 -20240104112646 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F293A44B -20240104113126 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F454A78B -20240104113140 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F463745B -20240104113405 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F5472E0B -20240104113513 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F5AB6593 -20240104113631 2 6 100 4095 5 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F61DC737 -20240104113915 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F71C183B -20240104114114 2 6 100 4095 5 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F7D25F1F -20240104114127 2 6 100 4095 5 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F7E2A817 -20240104114209 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F81D6DE3 -20240104114242 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F847E7F3 -20240104114540 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92F95BB83B -20240104114912 2 6 100 4095 5 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92FAA7AC87 -20240104115220 2 6 100 4095 5 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92FBDD46BF -20240104115358 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92FC763BD3 -20240104115645 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92FD89AC93 -20240104115825 2 6 100 4095 5 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92FE24086F -20240104120004 2 6 100 4095 5 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D92FEB1B48F -20240104121351 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D9303DEC3DB -20240104121632 2 6 100 4095 5 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D9304D97987 -20240104121655 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D9304F7758B -20240104121904 2 6 100 4095 5 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D9305BB0867 -20240104122020 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D93062D0873 -20240104122033 2 6 100 4095 5 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D93063AE3CF -20240104122233 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D9306EE09FB -20240104122350 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D930763399B -20240104122643 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D93086CF9BB -20240104122651 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D9308730BA3 -20240104122926 2 6 100 4095 5 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D930966BF1F -20240104123326 2 6 100 4095 5 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D930ADB4A27 -20240104123447 2 6 100 4095 2 EEB25F20046DA7CBAC47745F4C0F4B81D854E699C4761A4175478874F20DBA865A392640F8B584C4B9B4B1731A946DF7A57CD37B61BE3964194F06CA3A67C34B26DD2BBF3028F0239D0D947FD9A2AA9B38374FDE72528B7FA745F09DB9C1BCE23028F9EC17D19F25F088E0242B5F3554541185A9A16858D1553CCB603778B07887190A898727269B4228247FB3CE1AEA89ADFB3D11710243C05FA76BC3556B980B039126B0DA69D1FE928F77A4F7920A1AD89BCBF2B78B7D602BB7AF9C16F0E208C0C7500F6DCA222680C786E43DBFC1003AA1977EE65498C5245F14D66BB690B6786EF3AC4E3422C10C8D016EBFA509F8E68E378E1C4910400FF13C318C1072C0AEA5864E211D088A7F13B6FCBABFCB2D006C7E5F22D149078964A87C31FA80A570DB73D00B178CC34D4A5BEFAA270EA30F80184F4FF98E1E0A6CB45474DEA9381A8871519EF3C1BF1F68378D8DE6D11966D14EEC08EC96A656E677A35B415D56711D16FF912CD2A30DCCE1CBB648437D82A73BFCBD4CA25DA1CCAF9F49646FA5F420C3F6CEE4A5A19DF750E9842B460025EEDFDF208622435D0205916B75EDB72050CDE2B51F9C37DD99987C8957FE46DBDD97CE5BACF1A0CD04FD82309BE29809714DE6F0BCCD73B9EF1BCEBE57A7DED76A1BD19F2237704CE93EF30725CEA5E4EFE122A782E53E6474D5A7AFFC75F1D4E4CF2035E3DA53BF7D930B505B73 -20240104123558 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE029B533 -20240104123620 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE047224B -20240104123807 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE0EBCB87 -20240104124250 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE2B0F0D7 -20240104124501 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE36ED43B -20240104124512 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE378775B -20240104125156 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE5F9437B -20240104125510 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE723ADDF -20240104125525 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE7329FCF -20240104125540 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE7439817 -20240104125851 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE86AB4DB -20240104125907 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE87B66BB -20240104125924 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE88F2753 -20240104130222 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CE9A5226B -20240104130442 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CEA7DB5B3 -20240104130643 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CEB398DAF -20240104130657 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CEB479503 -20240104131100 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CECD07E8F -20240104131128 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CECF457BF -20240104131223 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CED437003 -20240104131543 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CEE787A6B -20240104131552 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CEE7EE587 -20240104131707 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CEEF11B57 -20240104131858 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CEFA09947 -20240104132135 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF0963173 -20240104132305 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF11E122B -20240104132442 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF1B47BA3 -20240104132621 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF244368B -20240104132834 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF3139187 -20240104133205 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF455DA5B -20240104133257 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF49FB7F7 -20240104133331 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF4CF5FFB -20240104133444 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF5392DAB -20240104133611 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF5BB213B -20240104133702 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF609579B -20240104133750 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF64F4693 -20240104133858 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF6B0B2B3 -20240104134528 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF9174353 -20240104134709 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF9A9D48F -20240104134725 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CF9B8ECEF -20240104135017 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CFAC6EE33 -20240104135028 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CFACF7567 -20240104135526 2 6 100 4095 5 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CFC9FDEEF -20240104135617 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CFCE8DB8B -20240104135643 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CFD0D1E7B -20240104135715 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CFD3993D3 -20240104135931 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CFE0D249B -20240104135940 2 6 100 4095 2 E8BBED0B2C20CE2D6D7C175858DF5007987AB4AC62559BFE502866F4BA984F41EC586A62B79DE81B818784CE66B4EF6EE06BE7C4242BE2A6DFA5D218E9D073A4162F0B05A1381AFCA6A27565DDD36D1EEF0812AA0CC37C3FEBA6CD728F8DD8FBBF5FF2C25C2D5F456EBF9EA83D6593AC7121E157F17101AE85DAC1B747A915C52159948A190454DBED5F7016F43D3F3BC2C496D6DE2A5DF17872B59789A4E5F503C4F1F096A3A9DCD1CA53D5CE88F6C00959DF042577D064467F375AAB350DCF6427078FAC4DB76E56A80A8AC4E3F276A2DC2E51DDB75F921B2F7A3C51D957B8A89F806FBD5879741438194AF82FC33DE8B5AF6D6D63A750DC1BC18A063CF6A824276A8F2447707DD110425B3644C19E3BAC8FC4686629D90101340691D026B8184EC4872FAC2A658FB8A4BBE5DF9B2A8A17D675FC9EEA09D12A8C8D7914712D21032FA35B056A95C60DB9F464EB15EC04C5CE8958A8CCE7600A207432BD6DBBDAC099DB42A6FAB7297FF7CDD77A80A245A16A9B01FF00442F0259EDB26BFD04BBF58E8CCD98C762BD1BFCF840398A5DF817F7632AEF5C1C9E9FFF766474308918E5D309DD318D0BACD2A75612BFE40FFCD6C14B55A96072C3FFC5F10DE4A3FF9D0DFCEE2EF21517D3095552873C9C875FF91E4518545D595B02B69D3E0CCC370270A0356F4CB3F7E0177557AD5AD730955DA0203EDDC3C19DE9D73CFE126753 -20240104142106 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1710332DCB -20240104143451 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1711E1C253 -20240104150313 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A17156243B7 -20240104150556 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1715B0C103 -20240104150825 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1715F7F803 -20240104152907 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A171886D57F -20240104154312 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A171A440F23 -20240104154730 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A171AC37183 -20240104155021 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A171B12B0DF -20240104155636 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A171BCE9CAF -20240104160727 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A171D1EA6C3 -20240104162058 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A171ECBF4F3 -20240104163450 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1720828973 -20240104170537 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A17246219FF -20240104173739 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A17286C63FB -20240104180227 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A172B8A314F -20240104181102 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A172C9D0567 -20240104181529 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A172D236A93 -20240104184018 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1730435B07 -20240104184554 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1730F0EAAB -20240104185310 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1731CD5F77 -20240104185350 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1731DAA9B3 -20240104190334 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A173307F9A7 -20240104191938 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A17350588AF -20240104192635 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1735DAA9A3 -20240104193532 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1736F11283 -20240104193805 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A17373C750B -20240104195916 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1739EBDD33 -20240104200312 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A173A6430BB -20240104200754 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A173AF2A68F -20240104202320 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A173CDDF643 -20240104203508 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A173E54E6E3 -20240104204338 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A173F5E5ABF -20240104205043 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A174019A1B3 -20240104210231 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A174197571B -20240104215505 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1748451A43 -20240104222200 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A174BA0BE73 -20240104223343 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A174D1343FB -20240104223558 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A174D50F24B -20240104223657 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A174D65D7C3 -20240104230313 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1750A0115B -20240104232200 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1752FC1F4F -20240104232649 2 6 100 6143 5 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A17538FC137 -20240104233816 2 6 100 6143 2 E26B3DF44B6BDB283DD87C8FCFB841E7116C771B87651254D58C3ED54FCF6E041E04B189F53C0AAA9838EADA85D258A70516CAFE7752EB065542E89F25CFD74BEAC3A0B1EDC79D677137E229915D5E7F9AEC2386582B4E069651943CAFE738A6A435BF75D91B4ED92D571B74DB636A155162D8E43D2B3889E09241842FCEF7FF9841E69942817C72C20A23B015F781AC740D1FC7CC9CCBF98D8C92CAB153F8CE24E540A2325E9769AD8F4B6DE329919F797259B691DFF2FA06BAB66E11E5BB5556D8BADFE3F6B41EA905FBB17A7D602ACDFB98BD2F7F80204329121D3607C64547FE04E34A9F6C14F6BA70ECC6929880A305B6C647F4D1E3B4257FD60666C9FDA9E44F5A3C76818054A2BE034C80F7756854B8AC3694412A8632F10F794AD16EFC696C2B792A906F7E8B9B99086DB52C3BC1436B1D8B91489C1D7B910204DE03F8D837989BB65C1C69E35E5F3EFB61F79EE8877880ECA82F1A1CC886E4FC72EB5AB28A77584C11B8D26BA67F1E07AFCB19F478AE21E71A1A48E9ECC05388B7AE6D053EAB219F659D6353412261BE121E30F35CFB527FCFFB9EDA780CE6B3AABC281018EF7ED7612AF8E877496C8008229786D2656FC13028BA3AE818BEBCF5089ECC8C7E91CC8866838BCB4F605EC8C3CB236523C1F3FE67C63AD9E3C03AA7A8ECC2C78749FE2CBB046812E823750EB78124A61932972AEB7573BB7D3DC47597883C0B4DADD75E1D4752C08DECF2345B9A2DB5655CBF056843DC655FE0EE540E0A80BD113BCA208DC60C30A98ED742B262126D304A51D763A83F6FC09113F6DDF3583AAB10A6D16856900D1F0E0B61214DBAB00C353ED0A7D9B3E02A5D4E0EBAA6974408F4277F7C191CE9A7941FEBB456A38C6841CA5124D6B23373F97C6428D7BA96F4722B8110DE4078C3570E663039BE9B7B20C90474FE759C9391CFA635EC3D89CE491318DA89877CE31782F10F053F46DED6864FE28970C605E0B1C5D4BFAFD961DFBAC5EC123626D9B55592713918CC21A1A522FDD0C407E42532022DBE030A844C8008E184DDE76EA3F8B6333BCC27F23BA58170CE691A1754FE4CC3 -20240104235816 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E526A4027 -20240105000102 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E52B9D47F -20240105000341 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E5307C49B -20240105002604 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E55C8951F -20240105005413 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E594FDC6B -20240105011251 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E5BA98A8B -20240105013007 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E5DCD786B -20240105013213 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E5E08D3E3 -20240105013953 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E5EF3AD33 -20240105014506 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E5F8EAA8B -20240105014846 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E5FFDD18B -20240105014953 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E601A78EB -20240105015628 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E60E96A33 -20240105020424 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E61E408CF -20240105020757 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E6251DED3 -20240105022925 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E64FD3CDF -20240105024930 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E677F3A93 -20240105040144 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E7077E4E7 -20240105040715 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E7125CD47 -20240105041838 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E7292290B -20240105043220 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E7445EA7F -20240105045717 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E775FC3E3 -20240105050855 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E78C836D3 -20240105051736 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E79DB2663 -20240105053034 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E7B7AF41B -20240105053602 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E7C2244FB -20240105055132 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E7E0B5887 -20240105060142 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E7F4B55DF -20240105062354 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E820CC287 -20240105062720 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E827312A3 -20240105070333 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E87007257 -20240105070659 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E8765266B -20240105070824 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E8788941F -20240105071340 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E882B5647 -20240105073012 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E8A3A1757 -20240105073438 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E8ABFBF6B -20240105074101 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E8B83EBE3 -20240105075449 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E8D2D8B0B -20240105075939 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E8DC91A67 -20240105083505 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E9233F247 -20240105091527 2 6 100 6143 2 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E97244C43 -20240105092237 2 6 100 6143 5 FF5C5D46851A712217A7872DC20FF08EDD8DAF1F5041D8E35C2889494C9D8EE9313A8425B2DF8ACE596A9B3044564D2DF404370C9F2B819E5E3F75FCD6A119BC357B24671D1F6221E94DADF4BBA056785FA323E6BCD416DD8A11799D997E73C6A32602F35592F31456FDF05CE5BECC9D233D607E6A6E1341CDE092E04376B35A81668315141B9F3EB5DB7D28A92A85F8175087FF4582636A29EBC0C14C1F8664BDFC4B1C3A5B405D240E0A67B81D3E8D366DCCF8649FFFACC530FEB87866AF3E765E9C8B7B19EAE109BD9BDB184137C7218AF8FF1E36BDE8FD9AFF4E4E29E9497A5104502CBE8A3A01A0D4C65C605A81EE3C3AF59DAD4AE4062201FD1F0AE0CC8FDE86625B1209EDE36FD81D573BA35A1153F6273C3F5DDEEC3E14BB20F6392E937FB2C11005B762FB8E5A61348AAF6374EC3F3A27498B5CCECD5447F7837C21D9EA418E689AD518778A3B4D70CB8CCE215CF5407CA93A882B8463F3311DC1757EF00554FD187F7A286D03AC715FC2CBABC7A00037D91EDF450DC6A515D2866D71555AD4073A87A5488F804A391890A48B2C8E8BD5AF53C97AA9505166788A216634B62DE3376E88621A47E5DA1A783B56C3D738473E9D751CC570F7EC94B8D76A9350CAA57D25F8621A6CB03B68A2E01D9FBD508E8C91CB8859544490936D5FCF198F3E5ADDD2C0DB756B3A94D9C357779C1867265F7CBE9EC00F726E683537DE973E59C7ACD928FA91AB996906D8FB6DBE6F1708913008D08180A3DE71AF098A481400BB5284B02B360080118163B2E19BEF45E51AD3A02D34E92B369C227355EE5BD6316E07991B211A87ED8F36FE5337C6969F4B0BC9FF626C5468F88D49B5A0BE005DC89E0AF7285710E14FC683FD9A99AC86749D8E1FF0BAC1CCB6D734BEFCBBA90F7F0D195860915578661F213012FB2C7F68C0E49D154B9D153D62C8C95084172A395F8E228688CE70226CA41435EB903E3EAAC6695BCE4E6AF36C63D387070D12009BE2B9ECAC9540896DCE83A4AAA6FF6F4ED14A169BC17A20B8AD165997536F55B7590483878B806458FAADC4AC60AE4326251A153B3E97FEE79F -20240105095913 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E29046217ABB -20240105101403 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290471B744B -20240105104919 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E2904974A54F -20240105113526 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E2904C8FD633 -20240105121046 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E2904ED8847F -20240105122212 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E2904F9A37C7 -20240105154705 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E2905D2EA893 -20240105162329 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E2905F97BD13 -20240105164947 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290615186EB -20240105183728 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290687AC4D7 -20240105184151 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E29068C000E3 -20240105202016 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E2906F571D5F -20240105214209 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E29074DB94EB -20240105224349 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E29078F088AB -20240105224824 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E2907938DD5F -20240106020909 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290869AA027 -20240106021855 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290874189E7 -20240106035257 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E2908D8EE727 -20240106044018 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E29090CAEA63 -20240106044946 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E2909163261F -20240106045528 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E29091B93073 -20240106050848 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E2909297B81B -20240106092208 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290A3BCF3C7 -20240106101059 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290A7091163 -20240106101802 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290A77D0A0B -20240106104846 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290A989844F -20240106110203 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290AA67622F -20240106113157 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290AC6FC52B -20240106115438 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290ADE815A3 -20240106133228 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290B48CC803 -20240106133609 2 6 100 7679 5 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290B4C4DBCF -20240106134717 2 6 100 7679 2 D1501303160348FD3A7B93C0412E414592732D1C3780B7CEEAD4867A47FC4E561D607B47D1B05E93FAD668BBBB5F21CD009E5D3C9D7870A3FC811AA616A4F50A5F8A73DA799E4E2959006D1FD23D3DA241E8F5F7674904B56058A95AE30B7EB8ED4977C93E6C3460E0A4421B1BC044A93F71B8FB60C7EFE4B4C41454FF7BD38D5447AF6AE20D826D8244F9396EF549DFF6138BAE6BDFD3B1F2E1125365761CE905827D63F39605B703FF39EDA7A239D553012FAF6C33A327A4447868A9321D30ACE8F0DA43427BF73595D41C089F2F817245FCC4B38AE3DCDBD73C2F82386E53EE9BD4850754E21060B0688EC27CDC2045216E1FA70770F420230D8923361C30F10340A1715B1F642DCD397A5A3BA28C59B3F29818B896D45DD6B12F34BF69303048DB6A8DAF68F3DE4E9CB902C56D511578873A30869642961B242625FA41B5059ED0C9098DA1FC8EE928B6E5429EAFBEE721D5BAD923B35046CC09E85E1894FD0DEA671DBD5DC2FD42CD8FD2E52379544212ADE9F755712515AF31F47372F6DF80C9DAFF562542B7E26F32E373C5C83222FA83356071175C44F639B2711C7B3F74063CD8FDE5ED9E25BA806F4BE2504C339F03A1B9ABE0979D181A7F71624E2AB1DF6945C5FB419727BABFD9755A8019DAF7607273B57C7B9A802928D6C3B377E621988F6DBAA6FE322F14210244C1C3EDDF104F73D57A661F8CBF117D405A18E1B176A705049BD696244109AB272F4C5352C456D4C04D2A6001E1626E6E038F48093B3EF619B7BA9002A7E64BEFCCA297D71D08EF1C0E99962B55EF85CCD2F111F51AEEAD99C3085BC9AA936D1A55F5204281860E33EA6ACCC22CBFD6A1AD086E44B43E0E445B22F0A7222EC3417619461BB69E27B1A931EEECECA667DDF6A7AB24B3F369337F261A99DA78B55FB24FFFF315FA48882D70446E617F7804E8A743AAC7CA0A1F4FB3C31E37E0D51A6EC1E923C110763047E9AD04B1A321A3E3993D7A4C688DED76FB6B907D80DB3DB89589B98ECE42059630FE74FE945B0A92888B9D3566CC0384DDCD92C4B0455D7B5DD39E0A0DFED6C96A7C4B5095A231E67E8AF3D70742F37A4DEC85B0E060D7F304778062F0F4C3CE4019DEF66484000A0A79243EFFA5927813B30B915F454CD87A13B0B0403E65970194C98F042F26C25462D0F749B5255A5AC0D294DE30DDAFC1AEA00C7D280555003FD4C32C5C9987405CA4728104E469487794B3616BABA85B09A7369B8530FA565D2B04736386AD8938B8CEDAC0B1B9FE073B21B4D402BDFCE7AF4F8F69FD6695A013424FC8484AABAA19BDDFB74E1935EB972C6D6C0CA9E9A3C07333788552B446E290B5751C53 -20240106141837 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7DEE2E4EE3 -20240106142436 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7DEE8A7CD7 -20240106144829 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7DF015742F -20240106152038 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7DF234DAA7 -20240106160105 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7DF4EFC613 -20240106163121 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7DF6F6E203 -20240106163448 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7DF72A0C27 -20240106170007 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7DF8E1C203 -20240106175041 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7DFC3E7E5F -20240106184134 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7DFFA55BB7 -20240106194104 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E03A6612B -20240106201237 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E05C48B9B -20240106203135 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E070747CB -20240106215140 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E0C7B892B -20240106225612 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E10CEF363 -20240107002641 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E16E9D69B -20240107012956 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E1B324EEB -20240107014336 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E1C0FDB2F -20240107015412 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E1CC29D5F -20240107023117 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E1F39A223 -20240107024430 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E20145813 -20240107030408 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E2165D633 -20240107032720 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E22F0D6AF -20240107045444 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E28D2CA07 -20240107052034 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E2A83AF4B -20240107055000 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E2C7678F3 -20240107064332 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E3017D303 -20240107070345 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E316A269B -20240107071248 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E31F72497 -20240107073413 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E3368806B -20240107075627 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E34E626DF -20240107092923 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E3B1B9373 -20240107105443 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E40D41C83 -20240107120213 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E4560E6C7 -20240107121141 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E45F89EEF -20240107121703 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E464C599B -20240107132926 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E4B161313 -20240107142507 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E4ECFD6B3 -20240107151843 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E5258293B -20240107153743 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E539E84FB -20240107160830 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E55AB3C8F -20240107163047 2 6 100 7679 2 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E571F6DD3 -20240107170058 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E591D8A17 -20240107174158 2 6 100 7679 5 ECDBC2E7C98E3D4FEABA99C3FA3EEAAC6305023D95B895C4019BFC22601AB5F9D51E3CFC909E5B963B2C52654C150DECAEDA6D0397EB54F1DA714D70920CF4054E02B5CD515C51FCA359DC1733120FAA30541BC2707C9FA7B973464558F6A7119E9ACC9F0A62729B41A2CF697EBA9E646627E8DB08E967447517B31844C347B02576F9E8E9B80FBE14E5C1D42D5CA233644FA7652130878CCF740A59F20835B21FFBDB2B1EDE638AF89D50A3EE7E31E37DD712FD021DB31EDAE2981299034B6C0E4F99E40D4D8E179F384931DAC81A266507E586A01C60BBE107F6896ED9DF8F8CC7E4E50EEC3EAE34B00817FF531413A27B3F8DFFCBC297043E769DDF8CE267AE314F9CBEBEFBC43D46DCAA1948E1626094CF1D7109AABBF971D76CC4C8F8FEEB211BC7DA3748B0341C39126FF72497F6D0B4800CD8D47A1C64565C752ABD83B4B013CEE0547BE9EFC0C806F9B9318F5B2E34573E912A9A18A3778F82978BF2AB2ABCE38BF82F77A1FB15D6675BB0F881E2963686E2AF1842085AEFAF65DF160260D788DE8F1D955D89B70693E70F58EFE6E3B1C8C3852031BB44A17905DD9F083BFD8A8A4F08E1CDE8434B0CC84E9F119C0D56012FFB5854E3C427EC034E085733B77E072FE074714AEF51D8378774BCB2E7A38BD8FDED53AF1D086A508D90A2FE7AE66247BC4A476C9462FECD4EDF39147267EBAEFD44FA45E2E55B320E912CA67ECA0A768BC573B2639F3DC4D36CA747008A0B4EF891422F66123072F66753B5594981EBEC23CE739971AF90DB0822B1C312DD916395CAE325ABB2AD544C84C79C645095DF9BDD20FE6499B6999E471E85AA2012F38927A5B3AB17AA10956C240D9BB1151E6E83700C3759D74C463B56D5D215B812A5A5BA859B4237EF0E23D6C086A9A25A6ACCD2B830F64F677F83531CA0FDCEAAF65B96EF4C9772C73D4627BEAE8645ED34404F8A2F4FAB1FF4F56E28C5CA1D9AA227FD95DF5113FD07200E3D10065FA337160E544D0027C0A82B049204BA0A544B5E32B3F08B76404A85E2927630EC0324A50632657543A72E481F5418B1CB45B1DB93AA66539FF4A0120599F87705284BC1AB03EDD8FCFC9C0C2C4BD58276C1D4AC3680B05CED61B91AE9791140655A229D776900DB47379B99EF8ABF851E2F61099BF43F6870E1EF5D03CAC45D00F6927601241AC087C235098CEC4AFDC9DA8586108517F7D4D761D1FEA18110825E5EE903ED3562BF5E12A2C2A3B295553D3948A1B1F28B6B0F7D9C94D9AD634105D2A8BCE8E7C93FBF9CE2DD73047F6E1B616188375F94B3CDDC878B69C4FD9D918ED35FE45659093974E46247F09B8D3C23DAB5DA7E5BDEE42F -20240107195132 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C0BF412DB -20240107211121 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C106F1A93 -20240107220224 2 6 100 8191 5 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C1347F0E7 -20240107223011 2 6 100 8191 5 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C14CC844F -20240107233406 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C185DAE33 -20240108000524 2 6 100 8191 5 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C1A253E97 -20240108013639 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C1D6DA233 -20240108015050 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C1E2A0393 -20240108022016 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C1FCAB623 -20240108033300 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C23A9F963 -20240108082339 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C33AB6633 -20240108085755 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C3584E623 -20240108101256 2 6 100 8191 5 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C399FD6BF -20240108142359 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C47985243 -20240108150338 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C49B5DE8B -20240108163222 2 6 100 8191 5 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C4E9B7AD7 -20240108194900 2 6 100 8191 5 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C599C1087 -20240108204036 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C5C81D16B -20240108211124 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C5E307A1B -20240109020016 2 6 100 8191 5 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C6E22534F -20240109031529 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C7259083B -20240109032856 2 6 100 8191 5 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C73148B47 -20240109034303 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C73DA772B -20240109040437 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C7507EF03 -20240109045950 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C7828D92B -20240109064936 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C7E67E273 -20240109084815 2 6 100 8191 5 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C850D9B77 -20240109091115 2 6 100 8191 2 F601EC0972F67ADD6AA2031ABBAE6FAF062C5AD1619D32B18D43DB10D9B5E0A5E2F69321C963175289C7B809575F1CA9B1C51D14BDDFB5B9F825EB4F2890D9C5C0D6D03B42ED03B16816DA4213187289FC4F2C51710DF07506C50B2D0BD47A1D5EEF8832D8D62CE93BE30646F7EAAB30AD4C172C1F0162FDF61299C3EB1EB91AC76D9219DD0608C0640E080887E6BC4F076CFA6CAD2C64B5E2BA2803B13A34F28923897E861DF14CA58848A773F0B348788F6034F3AFAE3798DCDB196172229F7D9ED45857917411A1F4A79119F544B45CDC2F0D7CC8381BC31DF229A72CF03D150E016B3CA95D803B42463FAB8382B389A1B3FF4E76F2B4025E0872D28F9F4E356B9C967EE4230BB3AA8629626C12DD66282B0E2979F428F89131BECD4FEF45E028BEBBD3CA638F71F8832B7552212BBE1C1A2F213DC579E227285D6B1511303F6905A492CC08BE2361EA5E46A66E0633D35819FAF6B7DA7C9BBA485E2813D0122ADCFAEB5C2991AFFF76A7A746CCC4F9A40DAA3870FD943E92F3BD8F65CFA997A3635EE9F3BBB3D4E229AAA64F6F53C56F02E65DB06ACD2182FB013FB2E33EF6D8D2A40C9EE3885D7322B4F87F2EBEA0A799EF949BD7CE9657CBD7FD75485F7B68839167FE40F20C796B4CFA42FAC5593BFDA46FA6E416BC688D33426B0644BABC0E52CBA377CD0A3CC0D159A7B003F3BEEB9405B160D55264F7A31A52A9A4C7A1576494BC994925D574DF813CFB2C0DFA6B92B8EA6036B2D4CD5E54109F722C3F75690F3295EEE4CE512612711B1E59A0600701A8AA90D4FB6604B765E0AECB664F2318B556A2C1645865E1CD30CF50FFD2F6A8BA3D1642DEDD67F3E1B0516205F5EDC25FB21217666A1690DED31BD0020B6F7706C9E499EE23B2BF9265E43C23CEE5CA5F9B70ABBC437E8FBBD0295E639FB4858A99A85DDA4B3058145F7D2081A869C3D8A775DBB3FA66DE5FD1DD8278E7627891B845CC8B2918DD8FC21112F3D1AE4EA375AEC71F95A0C02251489CFDFC40272F8BF3C04469E5FB196C18081E94EB56731AC5EB40E5476B3D8743E69BDD7316C9ECEF9FE30FBABA7B4483CABFE9BF91F3BC536F022DAC1FE2A3E5090924CC23EC793A45DC9BF88384CA6152A82903C107517D3252E3067A2AF52E24A3B0A9B7A1CB9F8FAC05C8CAD0729A270432A437A5417CED21A7BC11086437A104C05D542E5BC3E106DCF2772FAE6A90E3FDC1F3397C3E0A16630EAC1F02302407B453C4B2956FB8BDACBD8DB142ACFBFC8345F339E89B8103D2C5AB252BAB6B78BDD869F2A0FC7A9ABD2F4E5DF78E4A13EEC2DCF0B90FCA6CE7E255E95CD5B2CC59855FD7509B6C8080ABBB205F01186E25EA88DEB918EBCD5D62D3008DC8E93A4C31C379A388FD58E92E0E1308D30D66DEFF4C02C46FAB280FC61FA205B7A7D074582D40BF4B5EE4B87C86562483 -20240109102754 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3113DE49B -20240109103838 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB311CE7D53 -20240109122733 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB31802BDDB -20240109144019 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB31F830A13 -20240109151803 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3218C2C43 -20240109172004 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB32877BA83 -20240109173200 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3291AFE77 -20240109175727 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB32A87A0F7 -20240109190851 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB32E84D477 -20240109232421 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB33CD99FDF -20240110000155 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB33EF7933B -20240110004723 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3417961D3 -20240110033004 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB34A9B46AB -20240110044250 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB34EAF64AB -20240110053016 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3514D538B -20240110060245 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3532513EB -20240110065303 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB355F0E0D7 -20240110065533 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3560D1433 -20240110075227 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB359366F87 -20240110100015 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3604C809B -20240110104106 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB36298E677 -20240110104740 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB362EE1733 -20240110111504 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3646C34FF -20240110112023 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB364B02F03 -20240110115553 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB366AD1CA7 -20240110120601 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB367384E6B -20240110130930 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB36ACD8457 -20240110133324 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB36C204A5B -20240110144137 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB36FE62043 -20240110150954 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB37171A81F -20240110152353 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3722EE947 -20240110152557 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB37242E447 -20240110152925 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3726B351F -20240110161518 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3750124BB -20240110163930 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB37655D503 -20240110171223 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3782C4503 -20240110173427 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3795E162F -20240110184239 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB37D2F5503 -20240110194145 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB3807A121F -20240110194314 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB38088267B -20240110200018 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB381776C63 -20240110211339 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB385922C6F -20240110230519 2 6 100 8191 2 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB38BF1EC13 -20240110230904 2 6 100 8191 5 F7D2DED9D5BF8F08F6729427B4FA345B673D55A16502D2B438B068D893B7FD078638BFC485EE380DA4F972F1E2D28F9DE0C9D32CFECE54C8FFACDFB01EF0CFEAF7E644667DAE998AC4E387CBB3D7A5E4CC822EAC7D515E6FFC76DF221FCF9C75B443A10C349D01D7B0EDE446DB84A638E4BB390362E25201D2B3766FAB1C154B24827C9DD3F26018960AD84D599FB5F0090E321AD891DBB94B9E755CE54B3A99BE00CE2CBA594205B28F277FB3205A531709AC7753EC2C38CEF555715CC56FD88780779CDFED96E1300F705E6426C9420275C5CFF3A5CEA59FCC57EF776B98DB7B23C1CE34F6097E778B6DA4AE5593C3827DF62AE582738497F51A089E30DCC44FADD4200A72DD9C11E645C56085678687ED0BD12E6C862EC0BA0FBEC9B5677534D83335C5550B6A04C6D52189E396CDFAD25D56344300D17DEEF76FA106741EA0A164EF404EBD6EE03ED514D3E0443B8C30535114CE68B8507B9C3F7F942E1E4A86AABDB9DF0D688842E9AB8508146E08F974FDB3D7E07DC7610FC4BB3259FB2F1FB9142B77640715690A53E6B9E1CB43F270CE35A585BD6BD5F8E7415C27273F0B6C040D4F293C71FFAED61319DAF9FAAD3BE65671657B7A3C1F115CE315A3C329DF25DA1C3CC8EEA18AC8BCDCF1E965B573FC5B194AF79F04FE7B3E28347EB73F12F19B87548D9A34DE6820D78D5490F93B126A0ECB6696E32E917EC922BB27BC3DED89EF206AE1917F74B4C642043C54F77AC8B9273CC68BE4A1131E634263057E10C97C866934AE984D8D4D2FDDF833AB58AAB209A193D0E6AEDDB70A8E6AD7DB2090412118687DF9817B1D81D00C64925A4995F19368813CCFC1D13BAD28B8C449A71FA42CEFFB1251D7CBC01875C80ED21FF370638E4EBE5CC4EA7674B24599826390C84DA1F292E7B989E838F047ABE7A075E357D90068037E886ADB9A869E0C62513A7E0B90231AA40AA8F96A5A795482410EB3FEA4D1CC5549CD50FF2B2AA5A42DB4366B3CABF54EE92B830D8EE77293A03E436A637CFCA3FE7CF60B662FFDD8C72516C2F2370978BC2DEF32D88FB55801D1E22878C8C86B7DD63077A700639A95A30C7DD522943D99C9CA17059715B6884FB786FE50994915D41B0D9DDC8AA2517094CFF9C1769E05F548C5222486B798EFE13788351E986CAAFFE3D95A0082C822CECB7D55FBAF4DD026849765690E283433B0B6B0060533863CA03736FB7973BF83EE5C12C1A3FA3F4E64A23746A9DB919257C06ED0918FB1BC8D28EB4A72DDC37954680C91FF58811883342B3FE2D8FA68623C139BFB6843E858156317C8C803D5971871F2A55C0A36CC5FED30733FB09F6F5D87825300E543B02DDCCD6C4CE68E977C7EA824B5E9EC28B671DC4B28224C6CE43F2BC3B729E3C833403C2FF9F082B2445368A132F97C088E90367832BB69F5C54CB38C21AB87 +20240828044144 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF63216235F7 +20240828044149 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF63217EB4CB +20240828044153 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF632197445F +20240828044203 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6321E28D7F +20240828044206 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6321F5D65F +20240828044207 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6321F5F783 +20240828044210 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF63220959FB +20240828044217 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF63223CB053 +20240828044224 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF63226F7A83 +20240828044233 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6322B452E7 +20240828044240 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6322E58253 +20240828044251 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF632334AB77 +20240828044259 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF632379357B +20240828044311 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6323D336A7 +20240828044323 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF63242A969B +20240828044326 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF63243E12C3 +20240828044349 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6324EA98FF +20240828044351 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6324F33C17 +20240828044406 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF632569D1BF +20240828044412 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF632591055B +20240828044416 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6325A64983 +20240828044426 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6325F39C73 +20240828044435 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF63263987CF +20240828044440 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF63265B2A5F +20240828044445 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF63267C888B +20240828044453 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6326B9D6C3 +20240828044505 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF63270DF46F +20240828044509 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF632725FB3B +20240828044510 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF632728D6F3 +20240828044525 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6327A20713 +20240828044536 2 6 100 2047 5 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6327FA0007 +20240828044603 2 6 100 2047 2 C2CE9B70B9DD5860C0846274F1FF29B2E3D5EFFA5A8568C6B9829BD8C42422F0BEE2D6D74503BCD91A002B09EB75174B87734CFFAC12682D49D50AF5B9837E3B30675E93087C5279A431B40D8219B2292A0EBB23ED0856BACF21F7A8C801FC3B0A1D2C76C4372109A24587D8E09F91CA0018EB2FB7D75BDD8FE230D49CC593E2152A7EFB4B7FCAA9228D061120DED56DDF6019817221B4D9A0F5DECF928148EB22AC583AC3BF37541CC285C6BB4E0C028E7140C133B12EB80354C01C053F5B435EA2798404749664674966DFB7113F86BC74FD37333330A664FA86AE1B40006717AC6091961C45164F3714777CC776DB2C7C72FA6A89EF3DEB98EF6328C7601B +20240828044621 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602100B138DB +20240828044622 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602100BA7D33 +20240828044630 2 6 100 2047 5 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602100F35A77 +20240828044634 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD26021010E6E03 +20240828044637 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD26021011F7EAB +20240828044646 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD26021016091AB +20240828044657 2 6 100 2047 5 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602101B2C867 +20240828044658 2 6 100 2047 5 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602101B60E87 +20240828044721 2 6 100 2047 5 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602102652CD7 +20240828044731 2 6 100 2047 5 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602102B160B7 +20240828044737 2 6 100 2047 5 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602102DA0A57 +20240828044755 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD260210367434B +20240828044803 2 6 100 2047 5 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602103A3B7DF +20240828044807 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602103C2D9CB +20240828044812 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602103DE1313 +20240828044821 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602104264E53 +20240828044835 2 6 100 2047 5 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602104909817 +20240828044855 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602105309B8B +20240828044903 2 6 100 2047 5 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD26021056A2A5F +20240828044903 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD26021056A52EB +20240828044921 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602105F6DDD3 +20240828044930 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD26021063AE353 +20240828044934 2 6 100 2047 5 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD260210651B5C7 +20240828044937 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602106651B4B +20240828044944 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD26021069D4573 +20240828045003 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD26021072D06EB +20240828045023 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD2602107C5C8DB +20240828045043 2 6 100 2047 2 E8198A1A9FF997DF62B131D5C187C3160A61128E5DC14FED2EC25E38EE627FC070B240AFA70179A5981739E7F1CC1EFD94BECAA338C8BEFCA1C036EF1F7804AD1BBE8B86C3BDDDA7868F9302E45F47BABB6A8D54E1871678AB37855761AAD6408EA4CEE8B4DE9A5972981B07EAC9CD496331C4E1104ED49ACB5F4F37DC9B98098C04053775DB2994B23CA4561C739DB5A19638C0D1D97C07EF26ADC912A5C6A3506B5E935E4C11E18769334B4D02CDB4802ACE68B55D2D3CD354B0DE2D4DB4727FAD43694110D90A4A18206A731466E83FCE2A6F8E042E1D244F7EA4DD2FF3B9E3910C2B7672E4605A2025BDAA0D67455F8FD50FD241B5074FD26021085D358B +20240828045540 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DB83F1177 +20240828045614 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DB8AA8ABF +20240828045644 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DB90E7B73 +20240828045720 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DB984B19F +20240828045813 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBA2CAEB7 +20240828045858 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBABFBAAB +20240828045903 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBACAA69F +20240828045912 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBAE15E2B +20240828045932 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBB1CB097 +20240828050005 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBB86CA4F +20240828050036 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBBEDB4C7 +20240828050043 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBBFC577F +20240828050107 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBC490C0B +20240828050136 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBCA8444F +20240828050201 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBCFC24F3 +20240828050209 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBD0E9213 +20240828050303 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBDBBE653 +20240828050329 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBE0AE17B +20240828050406 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBE8344F3 +20240828050430 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBEC9D58B +20240828050438 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBEDF58FB +20240828050528 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DBF858DCB +20240828050633 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC0619997 +20240828050638 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC06A2A8B +20240828050712 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC0D40C6F +20240828050715 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC0D78F7F +20240828050743 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC12FBEF7 +20240828050851 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC216E8EB +20240828050903 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC235154F +20240828050905 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC235B9E3 +20240828050941 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC2AA4F87 +20240828051038 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC36951FB +20240828051046 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC37DE073 +20240828051104 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC3B311A3 +20240828051215 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC4A3904B +20240828051246 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC502215B +20240828051312 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC5506613 +20240828051329 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC57E32D3 +20240828051336 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC58E630B +20240828051520 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC6DF9DDB +20240828051549 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC736A7B3 +20240828051622 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC7A11C13 +20240828051823 2 6 100 3071 2 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC933AB0B +20240828051906 2 6 100 3071 5 F0E30849E47025007BE82AED18F1B234816DC958D27A2133A1FEA5C9D5B00C107D4C3563B295FB10AA1BEFB5C160159F85A69C3990D6A5078FEE7D5462F14890168BF2AA6B06729778AF1CDA95F5EB5FD024D9A4B904FB6501213268D69167449CCEF555129648DA0C6C1500DB898ABAEBE716B468AFDADB8E499D0043B7D4070A957EF41EF2ED3D9DB4EB8607B620C714084F6909D0B980FC54E7BA3A4F7C6716BC8430C5D73475A95F64B8AA9BB6F9CD524EFEC35E322F10DA32826E005EBA1C81EA662FB1517EED4D778DB6658C7D6150F144BBA60DAE6B75499E70CD7D70842131C00E04319DB1B53867E6BF820B1D74692227A574F937B668F25017F6DB3D6FEB2A61F8E377FA73E8652089A0ECBE15AD1CB8C44D738AB114BBE7AB9985545DE182011208113A56C5D84D8E7640517C5EFA28670168906BA869583EFEE72F89C1B3CA019C4D544B711A9A0297911CBEEB124EA9D7076696F62AC9E8814CDA985B35800D4DB253497725F131169F56AF543DD51EED43501A249DC9BF25EF +20240828052009 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BBF34E3B +20240828052030 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BC38F533 +20240828052045 2 6 100 3071 5 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BC632227 +20240828052153 2 6 100 3071 5 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BD42ABFF +20240828052207 2 6 100 3071 5 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BD6986DF +20240828052211 2 6 100 3071 5 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BD7241F7 +20240828052259 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BE0ECA0B +20240828052336 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BE863B2B +20240828052339 2 6 100 3071 5 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BE899267 +20240828052415 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BF03197B +20240828052431 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BF33F3BB +20240828052513 2 6 100 3071 5 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BFBAA987 +20240828052522 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BFD18B5B +20240828052527 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79BFDA82D3 +20240828052609 2 6 100 3071 5 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C0656637 +20240828052616 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C07626F3 +20240828052621 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C07E39AB +20240828052816 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C2033C13 +20240828052903 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C29B2063 +20240828052932 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C2FB438B +20240828052959 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C35070C3 +20240828053054 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C4050DE3 +20240828053223 2 6 100 3071 5 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C52F78A7 +20240828053319 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C5E6180B +20240828053339 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C61E1503 +20240828053345 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C62B8123 +20240828053430 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C6B80C6B +20240828053549 2 6 100 3071 5 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C7B7959F +20240828053758 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C95C0E23 +20240828053817 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C9938013 +20240828053837 2 6 100 3071 5 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79C9D0494F +20240828053914 2 6 100 3071 5 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79CA42683F +20240828054013 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79CB06EC0B +20240828054258 2 6 100 3071 2 F92C6D0F2F9D19FE24813B351098A85FABD54907EA3F2B1DDC129631277DD947357AAEA3FBDAF717CF7FB244ED5EA7475AA7AB9F8CC8E92BFEBA6B9F4394EFEFDAB17F42338B58FEB6B09CD728221C9261C1FB59A2EEBDD7A974CD3D56031DA903E422D77061725705DC1366F17C530CFB45A704C00018D78004241F3CF6AD1C934F576F8D4C542FD83BBE0C8C3B122063A7457D3A47D1EC0A2266A36ABB664E96959D60C46344757771F7DBD79B25F033CA5E7674DDD2AC03F79C7C8E2B637CF3C9DD55D3FD5BDDB1CEE1B5F57B72B01F91BCD385AF7AD03C183EA95D95D07838BE129BDF7B724A27FC2ED5AF6AE17C995ACDB42C783845342A07BB2318A392B21912B8E4165B1A4688C35FFBB23B733DCD0136373E308F9320A5C2BAF95492F6E4F5964B18917846376B2ADB2E2892B1D51DDC63578DFA361EA5190E39B6E93772B2A3F66CD6B0B183F41A68A31AA7E9A23DDBE383AC2E262C368DC859989BA361A683A9B7F3B158A1BC9ECF4F8669F363DAF10ECE0EB29581CB79CD234BAB +20240828060009 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A70951B13 +20240828060511 2 6 100 4095 5 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A726F0C37 +20240828060714 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A7335AED3 +20240828061156 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A7501901B +20240828061217 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A751A9A43 +20240828061522 2 6 100 4095 5 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A763D53FF +20240828061600 2 6 100 4095 5 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A7675A20F +20240828061619 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A768B4D03 +20240828061636 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A769E17B3 +20240828062452 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A79B996BB +20240828062521 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A79E2492B +20240828062623 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A7A419E13 +20240828062831 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A7B0C50CB +20240828062854 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A7B27FC2B +20240828063249 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A7CA08843 +20240828063334 2 6 100 4095 5 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A7CE52E4F +20240828063443 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A7D4D4863 +20240828063548 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A7DAC7243 +20240828063629 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A7DE88D73 +20240828064128 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A7FCA819B +20240828064626 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A819B3083 +20240828064816 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A8247AB73 +20240828065323 2 6 100 4095 5 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A84385B67 +20240828065513 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A84DF9C03 +20240828070128 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A872AEE03 +20240828070200 2 6 100 4095 5 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A87566497 +20240828070537 2 6 100 4095 5 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A88AEB07F +20240828070904 2 6 100 4095 5 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A8A00154F +20240828071020 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A8A740023 +20240828071247 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A8B633D9B +20240828071353 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A8BC1DD33 +20240828071426 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A8BF0634B +20240828071455 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A8C19F3D3 +20240828071541 2 6 100 4095 2 C1FD462836A96C337420C7007228E616EC573732284C62893AB8CC4E3F3E182E3A2FC77E35BC37FC6A207BB3B56EEAD789DFE450ECA8A88518B4EBACEF11D667EA651A91285ED252C792EB32026784FE21B43F3E4B61DBB0E26D3DC6EE8B9090CCDFA2876C4CABA186BA994026CF4AE3D17DC5A0D1B4D70F58EA021ACA38F9D1EC7CFF066D1F0C1DEEAED46C531E9719664DC3AD0E61FE171E558BD54FB13004B7E19B3AD908A5FDA716B1AFF98F48527F12F755CB53E0ACE01192CD0CFAA0B7623D1E035DED85CD39B69922E719FFD315DEADD6AEA9064B7DBB7F1079FB06C0442AB9E364E2E756D6EA8C07A92E9BB03EA11678BD0AE1ECC81748068B0658EC1E0C54886933C5BC69BED9334255F55748403F957CE5F314D8F154E213068BAC299C0D323623D4FECF1C17601E347500A00F8AFB1FD63C936842FE87831519613BD966C1653F623A42F236CCB0AEE2E81F702C8CC6E560999B686E3C5B4DE07ABD8DE477D0475F5CE1C61D3D8B1919C378D9AC041F21AC522530F7A4D62125D8DB8F8217BDB3E330A04758448AF7093A65591A0E7E82BA13F6F92CCC68AFD64A965D13A7C36ED85916B3EF9C3AB022E6F66A4317AA01B201BED766AFF938563E93784662AF2F72AE5BA52CF2B0C4ADAF6C20689296CF729D5A643A64A20E4380DE5E3C932CD162C12D55650AECDAAA74FEA3C85B534EF588D2693B7A8C5E63D3 +20240828071923 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9B3CF4313 +20240828072226 2 6 100 4095 5 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9B4F5B7EF +20240828072458 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9B5EF31DB +20240828073047 2 6 100 4095 5 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9B82262CF +20240828073253 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9B8EDB05B +20240828074035 2 6 100 4095 5 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9BBE344BF +20240828074440 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9BD60A58B +20240828074721 2 6 100 4095 5 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9BE6938F7 +20240828075138 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9C00C2AD3 +20240828075304 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9C0911F9B +20240828075632 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9C1E1F5EB +20240828080239 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9C432FEB3 +20240828080841 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9C68352A3 +20240828081126 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9C78B996B +20240828081614 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9C9536B03 +20240828082258 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9CBE55E03 +20240828082637 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9CD49EF1B +20240828082710 2 6 100 4095 5 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9CD7A6C07 +20240828082726 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9CD8C1A83 +20240828082826 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9CDEC8AA3 +20240828082907 2 6 100 4095 5 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9CE27CDDF +20240828083210 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9CF4E290B +20240828083415 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9D01153B3 +20240828083603 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9D0BAF663 +20240828083703 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9D11A10CB +20240828083816 2 6 100 4095 5 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9D18C60B7 +20240828084040 2 6 100 4095 2 E36F035A457FE7C42A6DFEA5F5F192B2FB147FA8B29FD9BE0FB4DB472F5668038712145FFD9C047435AAA518C55B975D814D566AA3233887D5C2C886B754D50B133FE132D81A0851637D6085F2289D8584BF5130452AD24DD87D7158CDAC16832D42476486F0EC2DBBCD38CEE963C5E367ADE50C9502735AD3583445AABEE10E63480E3791FFC7BCF4BD5C1F6E9768E1B1D9B6B75E177F95914B6D5F06CA7CB001B15CAD26B9C20565F8351E69B5E6CA74D30E770523BA7E05475050DCF81A3F9B7C38EF1C31447E35543AE5B00E0BB13C63F8F1DCE0397BF523882AB79E2DF4BDF7E18ED799142089E79CE6AC0E562A587B055D9F963260DAA84A1C520A0D46A01138F20B0EAF73300DD4196A403892EC30B2C84860C4EC4A1FE5778512F546F5B813380393D3BABC535668515BEEFA350207C3BFA1502B52A775146FA97E4CBF701C2DC7845FF604EC73052F217185E74813FD18D3EBA6489E0BD00852B156193735F5A34952DCFD4BD493ECD2C9948E9D4436A79B1F5B6BB7991F1253B8B68BA7511EF94B87D4D9843A5A510837C7AFCD7F42A9657C78BA516606F94BC27F1579BBC0776216AC8B96C2D6D485B6C6EE489C504E32A6B4979287D53E42D120D411F849C748B31FCB2CEB1663C813A0E327DCC18242B484CBF5F9191063933EFEC4C6A600C415B0F29365F6DBBD2DE794D7E14D62CFD7F1E570D1A9D26C42A3 +20240828090009 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F2258E4DB +20240828090718 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F233F2A7B +20240828091256 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F23ED9417 +20240828091549 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F243D1C03 +20240828092905 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F25E8D11F +20240828093653 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F26E25303 +20240828100014 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F29D9C7A3 +20240828100324 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F2A3C434F +20240828105814 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F3151094F +20240828111427 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F33641C63 +20240828113247 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F35BB7B0B +20240828113333 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F35CD9A97 +20240828113540 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F360A482B +20240828115349 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F3862A7B3 +20240828115426 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F386EC997 +20240828120438 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F39B5CC43 +20240828121629 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F3B334FB3 +20240828121657 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F3B3B734B +20240828122545 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F3C524DB3 +20240828123158 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F3D1B196F +20240828130157 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F40EB0D47 +20240828130238 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F40F7E253 +20240828134737 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F46C46D3B +20240828135646 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F47E7985B +20240828144149 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F4DB24103 +20240828145157 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F4EF2EE0B +20240828145816 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F4FB0AC7F +20240828151150 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F515FD9BF +20240828151822 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F5229B63F +20240828153933 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F54CF3923 +20240828154759 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F55E07A93 +20240828161625 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F598D643B +20240828162500 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F5A998FB7 +20240828162916 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F5B1CC43B +20240828163955 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F5C71914B +20240828164552 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F5D2E5D1F +20240828170129 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F5F34D397 +20240828172001 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F6192353F +20240828172046 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F61A3C147 +20240828172320 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F61EF7817 +20240828173414 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F6352E0CB +20240828173441 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F6359E007 +20240828180730 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F679AD6CB +20240828180915 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F67CD41EB +20240828180941 2 6 100 6143 2 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F67D23A63 +20240828181257 2 6 100 6143 5 FC9BE67A111C24C58B9D8DFF78C575F1AC8199BA90C7C86923636AEFB38B41C1282E5A8232B7B9AECD439830D372F7B8D22004BD6BD64F326ABA86F1FEA022C374CDDD3CA3F161873B1D51326B69BC26112479F45CDBBB0DF942D942333DEBECD3E705804408C841D2EA09535C2B5779315396B517A6C628C9E23DE15EEE013BB18D7B40EDEA8655765566F3923B6EEA21853E436480D25D1D7172F02B16814BE600FBE715963C7576E022AAA046EA7D25B4642F7626582BE4ADF0E251A6677DFC67C49260C444D7825A03685A5BD789A13E1AAF1970ED54C71B234682E3AAF67EEFC3875C8868086EE6068A48E6C4E7A7BBEE17505D4AB7E8ACA56E336490553B41E1ED5D023D2D2DBAFC3362D8CDEC1809F4A37845A1DB87AE4D7AE6F6D941B0AF97921C9E659331B524F47EF80EAF574D5961DB05724C17F45686389361D29A234BE063DA02D889905B8B1B5BA87355B60F5FB44CFF859415F439DAC677F1D5A1563B22236386D0CED95BE925C51D22F2173B579B1EBAE7E8B8EDB26A8532FD6DE7E1F33D6BF984BAF3AF00A2C382A7B354C77F029D041FB132BF27C430320DFAD34530246D6CB04D7A78F5364186A9A86B359A9F5FD28D4B9ABCF51BE2C955CF8102D64B322A50FEF96DD5C4D21268D7E044CC52AB57AD26BEFED1634C24BA947F1DBD024BA9A3CD94EEE0DA0CA9FD481BEB41BF6DB6ACF409E732C482643D5D5A5B720B26E618C7AA244B8F7506CB8FC8299195D03E30B03C6263A75AACBC3A32C9A7DD5D7653537125BC0FE7241A410DBF8E04ECCD1486DA3A321EAF36C5A5DC40A0FB262A64727CF7AE645BAF538E8784ECA49E1A277B29C56B8D1AFF2BE2E1665906C48A58230497091B47EF239C5D34FB19C25D89BB0B8573E8417AE90FEEB6FAC06F9F60A6C57F1D4E3325FB0AB1A3A088B4133A319158CBDDCF0CCC2938F64E0029F0389FAC55BFC1F0D0F15B2E70799562C53FC3D1D97CCFA25ED83FF115503D44A7A91FF295AD2F1BC598FE86B8AE7DA77773179A4A0EB0ED618102D880D9963798BF91EB6E16870A4AB9E8137E1D6503ADD39D8E8F683B05BF +20240828182555 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3180CE228BB +20240828184406 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3180F2F287B +20240828185315 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3181059FDFB +20240828191106 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE31812A21FB3 +20240828191122 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE31812A28277 +20240828195243 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE318180489DB +20240828195610 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE31818728F67 +20240828201325 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3181AAF829B +20240828202233 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3181BD9FE33 +20240828202820 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3181C96132B +20240828204913 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3181F3FE8A3 +20240828205946 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE318209CB6D7 +20240828211537 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE31822AC1387 +20240828220459 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE318290F4E1F +20240828224012 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3182D9E3A03 +20240828232844 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE31833F1DD7B +20240828233400 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3183494A423 +20240828235802 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE31837ADEA57 +20240829001115 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE318395E7B83 +20240829004718 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3183E0E5603 +20240829004844 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3183E34D98F +20240829005431 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3183EECD0DF +20240829010933 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE31840CEA00B +20240829014049 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE31844D61FFB +20240829014355 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3184533474F +20240829014829 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE31845BEB5C7 +20240829015142 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE31846235FD3 +20240829015517 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3184695C7FB +20240829020608 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE31847F7E373 +20240829023600 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3184BC56B47 +20240829025737 2 6 100 6143 2 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE3184E74875B +20240829031846 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE318511B9B7F +20240829033452 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE318531C0F27 +20240829034004 2 6 100 6143 5 C272750D88E88AEF9E0F2188FF6C61DE6B22B20E1C1D5A5E5B13A9C97ACB497B050868137519E1EC9CAEC9ABE3D69DC4C96ADA353B3809627C938691FCC17E260254A0ABF1FB7629416CF61DE72AC7B91EAC39F9A9CC38B729272D78976679C9F93E0E67BAC79B88598FA5B160A9403FB851D2046A6A319C55E028AF6AEDCE7588403635FDFEABCF52C2EB9D7CB86F1CEB17DF39D951744D332D51302626F56AF310A3E20B3BED391B713FF8589D35E44DE1DA41D70EE06762C2789444107C50101D55738975C05B61243016DBEFAF2521C724FCFF279D34EE418052A2AE927474EC5C055ECAB0B2E1F5E6EF378EEB15A7ECAB59638A0A7163577121789E3301236F63178910C6AEDEC6664DED0F0762D6F6854B44BC811A03E8627DB90D7A2E9FC85D32B498E8E5A92BC771A6D9C8E9A967F3EC3C0927926021B97FA8A201C22422BD61E330920F35AE966B43CDD8B6EC853AA8F1CE0C1061C152826F9769746EA7E06325B50A9C3D9B7A88C5D22B68556E24ADD0664F0230DF4896F53319223F39D68B6507E213ACD50EEDE83AAB51E3C4B020B6F0B0AB06CB071460D139DC597ADB530E51FEC7EEF6D5111BA3A7EE874B4708ADC8186D2D5326DBDF692E60C6170AE64590151BB6ECA0AA51E6233148C7D78034812FA93C6A7F7864182D576BB83714C3A4E17228B0D4569F70C451632477265A2A40B9419A13408BD7C3B33979589A112D6156484AD84560272D7717F763507AF92C86F4475669962B63A2BAB2EE0CAA835B90A7DB43CF8A2879674B60B1B1EC25933019968455AC054BCA392EF57C3C76D79AE684894BD009B97AAC3754537E85C93C9F96D59B8359C055B1B7109086E4DC7F55CEB628BFAB792B931B955AADA57FA6A8CB019B1ACE092199C0E5F94855DFBB08E3DCA886337842F363B8117751C5DD48DD431E903C2B1C7677FE2AD42A0CCCD2677B9A4774E9168A2C4C1B8EA5267971D0DD6BB91320A677928D2087069C7D460BB4E72698AED4F7127975D49F87D52724DE830C66F422547D0B934F32F4E9FC0617A6D2BB022987EE13330BDBA970A8FAE31853C097B7 +20240829043625 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD187E5F08523 +20240829053823 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD187EA33BB33 +20240829061611 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD187ECC3E213 +20240829064111 2 6 100 7679 5 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD187EE73FD37 +20240829065111 2 6 100 7679 5 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD187EF1CB167 +20240829082003 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD187F52294C3 +20240829091934 2 6 100 7679 5 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD187F92CC467 +20240829093659 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD187FA58CCB3 +20240829103319 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD187FE2DC683 +20240829123824 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD18806C1B393 +20240829130958 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD18808EFDAAB +20240829135456 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1880C119733 +20240829150211 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD18810B3AE03 +20240829152452 2 6 100 7679 5 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD18812362547 +20240829171859 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1881A26609B +20240829181704 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1881E2C3E3B +20240829182818 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1881EED38A3 +20240829184006 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1881FB9391B +20240829190814 2 6 100 7679 5 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD18821A70EA7 +20240829195154 2 6 100 7679 5 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD18824BB04C7 +20240829200011 2 6 100 7679 5 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1882546EC8F +20240829203003 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD188274D620B +20240829220907 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1882E2608EB +20240829221444 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1882E810C9B +20240829222440 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1882F2EBA7B +20240829230449 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD18831F68C1B +20240829231044 2 6 100 7679 5 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD18832552757 +20240829233827 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD188343C3EAB +20240829235120 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD188351A81B3 +20240830003221 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD18837F06443 +20240830011832 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1883B1C9E73 +20240830013013 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1883BE3681B +20240830014610 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1883CF597DB +20240830032931 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD188443580AB +20240830042102 2 6 100 7679 5 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD18847CB52C7 +20240830042255 2 6 100 7679 5 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD18847E4A687 +20240830052035 2 6 100 7679 5 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1884BDB09B7 +20240830053449 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1884CD217AB +20240830054036 2 6 100 7679 5 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1884D30808F +20240830060721 2 6 100 7679 2 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD1884F02040B +20240830071657 2 6 100 7679 5 EF541828E23A6BB90EFE9D9BEEDD3F9DE2E08069B8FD3ED88F27CD7E4F00AA272010368A26104FDBE69743D020951E909C76D9EF11E8050208720244763E9D59526B99F462FAC17E3A1ABD3B328C80753B1777D032397E4E3BDC90FB275DE027A21362A8FF88456ED3A9F397C045745B0C4D090D10304B86631AE9561AE9FD3C9FEB4490FD074E78702F4187A8E5CE8E7AE1E66593C34B9F08153994E70FE56B9CA823FCF1C176E875F6654CCECDF52463CDA61BE848C5B0E9CFF4E908CD0AA9BD4F4A58DF5996AAC3D411270CAD4BAC154467F91184713B4EFCFEE7922C8F58F9259937935A94A7791E99F4838EE1981A3EC9E6A2C44CBC10ACE390882CA40592D13E91AF49C78C4D518D9EFA98142A9102970E721D6ED83981164C488AD25BBC424C235C7AF62C4B4170EFFC11FA6EBEA4661D320013FFA6A4DA1EAE2F0545B95FD4E13B182BFEC226A01C3B46229FCE86A9E11B3E026326C1BA745510DDE4FCEB777BE42D1057DAD45ACEAB111C907760669A0C1F15DA4F5B8180E844DD5D602F7FAE7D16A5E8A2929E804A1BD17D38866A5EE3B1F50C3054C5E397969BCA2008DC96503513217BE8D2F15FB9DA26A8A5FE981111EC64CBEE1420D2DF7853B17E40766873E712977C1043237B39E2DE3868D079D96D76ACB24123AFDB5C6A6A9BCD40ED4C696EDAC4FE015CA982535A2A84B1A42767E1FBFB936B9FBD72CF98993C6B1EBDA16BF03FE325FA62511128CB669EE148067ED9A10338F87E4D3D39FE695A2F99B5D645A7653C3EBEA517FAFDD9CFF12B54E947A64BE8564A3851EA0F7A09C8C2E3D78FE0D3739ECA465A81194B8760F4F7213737C3FBE0E2F13704E7FDE2EDC91E22F1B76327CAA49BEBCDB1A33F178DA6F38666D09942532843CD95E61891A54EE7745D731FC2AD6B434D42F300D19176DBDD94594E3EB018EDC8666E89FB4C205A3D70F07F96AFA887F6D4A2FE573E77FDDD28D76F5C15C34CADDA8B9652FBEBEAA4CF56260833B160E8122141D17DE72CAF4859EB84CCACC341B7790A2D9B297538549451FBA5C47A37C7A99E31AED087BDF7F9E79D99CB6FADDBA30ACD5CF06FAC18DE33A94A8FC08ED8D93A24CDD7DAE09CD8CFF1C918173B32C10CE0F5EE9ED40D2BB3173370E941158C448617E4251E522CCE793B1A4399E8A39B923BC594AB453CE0145ADD622DCDF98D7D9A1E3C3C4BF128194857AC3959468BA2C2540EB5438D165F04D0A0D15BD19A5EBA1F7D6F82848877E480A20859C002F448716156AAD2008E4A7694E4F4C346C4EF359B21BB984C2073FE3E95DF3B183EFAC45BC426E3A569703F6C48DB20F7A32CB7E7C2ADD18853C7A8E7 +20240830084720 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FEF75703DB +20240830094656 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FEFB626A2F +20240830095006 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FEFB909467 +20240830110930 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF0108EC1F +20240830112637 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF02315BCB +20240830113545 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF02D19C77 +20240830134211 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF0BA3E697 +20240830134427 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF0BC3CC37 +20240830134817 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF0C009ED3 +20240830145923 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF10E44067 +20240830161320 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF15FCEA4B +20240830170319 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF197243AF +20240830171339 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF1A211BAF +20240830173745 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF1BC7E24F +20240830181908 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF1E96C5DF +20240830181940 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF1E9711DB +20240830183135 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF1F5C367B +20240830190740 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF21D6FFCB +20240830192133 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF22C8073B +20240830213430 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF2BE900AB +20240830213722 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF2C10C36F +20240830221923 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF2EF2814B +20240830225347 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF314EE303 +20240830231356 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF32AF8B0B +20240830234723 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF34FE61CB +20240831004647 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF3918C417 +20240831020149 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF3E4B559F +20240831022637 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF4002F243 +20240831030552 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF42BB548F +20240831033741 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF44F1D9D7 +20240831034841 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF45ACBE37 +20240831035452 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF460E12C3 +20240831053706 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF4D2CFB27 +20240831055400 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF4E512613 +20240831073419 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF5532694B +20240831074414 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF55DB1637 +20240831081807 2 6 100 7679 5 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF583421DF +20240831090302 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF5B405DA3 +20240831093205 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF5D338B6B +20240831103110 2 6 100 7679 2 D5949FC6991BCA2FAE324A3249CCAE8A99AEB0E6E81054670B5BCEA51FAB2D6C0A271648412828FAE2E356A85355BD9DF43DDD71F82F93494A6E4F0F78E998A4B13481478A814CE13A471D3BC48EF5A2BFDF48E920696BA74DFE2672ED7FC456B46C6CE48C129701E0D0DE344FED8581E2F1D010735EBDC6E9683D892CB2C2A164B500A5D2A9A41D8FCE24CDFD4A8DBAB66671B3FD8B6275C3482A10A73D2C1FD50627B4AAB5F81C67FDAA3D3AD28E916D9DF4F6E9035BACC614A3FC352650DCB94BBB4C3E40CDF33B242FC97C9D5BF655DF4672F496FA8B619B515DCB37932CDF25313659B982542675BA0300768C7BEB3EEC64BA9E0EB247B0B9D000E0BB07C3E054B5DAA9CE521C54EF0A1DC00203A4F723FC2361DAD5AC276C723044DD3B56A3B4C38C46CD3E9510AD9264BCB2AE52EA59F4B3CD500B7134135784D994C42CF8DCA5E90937C53A19D8DD356BB868CCE05A982F7204F1D3C19CCD16873CBC7CA44BA2D34B57E63F092B93C075530ED66177BE42F1677E4EB1A18EA0ED62C654F04B68DE9DD4A9C1AC509CE5DF1CF266C6A16696F858C024C16A95AF16105D9E778BD3A9FFE09CCBE4454EFFE6A309F629434FCB894B42BA2FAD7C4BA7091301422C347ACCB39FF801F97F36B3464A7B84C4C4A85503DD7BCFD97462AFCFDE1CF4C8FDA6FC5019B262C3E58C77E28BED5A2583B28DBA0E59D5665E7A5339A02C976FD31B4797DB945851DE5164A9AA3359F1A35E31357314DB6C82B5DB62D70BB7C22B3C110A0495E2B7200104FBD230C9C11824601EF4FA78ABDA0D5BF866B2CA6087E20AB2C8FBE1FFCEA5D19F11EB801002A801D9A72678009269FEFE57A4B8D389047D05F03C5472F5FB731C5BB3C5E2A9BA907D496E10FB953D953F650602639F37EED2F65424056F92CDCAA33DD65E714EF3D5419E7B4C1CE77A40D441962F2D42135ADD4951E90CC0FC85C2946C82F74C9B1398D6A086BC7EAA1763173AEF572969FA738EE079BF5C5EFAF8E4D99DB8618E646876342CC8BF3B1A62F969265FB633700F4CC598AB407F84BD2B1AD496AF8E785063078688A86AD6B4E4ED2CA31AF2F7899D0AD613A57BFA5746F743A62F66105DEEEBF637D9ADCBF941E4728DDD5D03AFE58EAD827B154BD22C00A94822A240DFE575479E9C00E38064BBBD1A5B511957045BFE40951312B2F5F5CC45CD94823AFC0CD2BE902C2E9DF92D87C8E24308E788EC48187B2EB69516AC9D7CA97C0E1C610320AFDC5767FFAFBBE16EA80B8E2CF1AA030FD86E803A19CC2BEF8CDCF8A7A1BCF82A1ADE289ED2733AEFAFA82296C331088447B110D8AC831708F631EB967936B2FF61456293 +20240831121754 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB1349E143 +20240831124443 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB14CB7AFF +20240831135558 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB18CC80A3 +20240831145738 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB1C36864B +20240831165313 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB22B0FAD7 +20240831185249 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB29880B2B +20240831185952 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB29E5889B +20240831194619 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB2C7FC84F +20240831230544 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB37F47B7F +20240901001522 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB3BE4A76B +20240901013228 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB404463B7 +20240901015829 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB41B1142F +20240901025646 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB44FDAE87 +20240901031615 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB461000EB +20240901042008 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB49A1BE47 +20240901044227 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB4AE1A82B +20240901064528 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB51D37F37 +20240901073955 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB54DB30B7 +20240901080825 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB56740653 +20240901083546 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB57EF4EAF +20240901093005 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB5AF60F7B +20240901122015 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB64814643 +20240901124800 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB661018A7 +20240901134700 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB695D723F +20240901135853 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB6A06CAEB +20240901140005 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB6A0E0D2F +20240901141551 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB6AEB6337 +20240901141841 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB6B0A7C53 +20240901144342 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB6C6CC963 +20240901151624 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB6E3F7CCF +20240901173158 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB75F13437 +20240901180438 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB77CD90AB +20240901182042 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB78AD2B63 +20240901193908 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB7D18983B +20240901195652 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB7E1244DF +20240901202100 2 6 100 8191 5 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB7F6CD3C7 +20240901210156 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB81BA121B +20240901220732 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB8571A7D3 +20240901233244 2 6 100 8191 2 FE0FE5928DE815B6A6B360EA50D7859C014FC47CB277FE8AA545E89E2D34791ADC80654D6B276978CAD4E12481459D6E40E32CD8500BBE14ABFBD4E72A14280C66F25A30CB81F885761B07BABB863C9DA0ABEA9EAC4ABB8BB272AD3ABA2B808CB6B12A4A5D68AF9B47FBF91C1AA08C7738B911583E29F339BFB9C46B193071A3BD7297521767A34B002F0EB1470246325AD1D48E7C7EBCFEED0866747ACC8FB2C731FC1D73C52F3868C1071D92BDF96037BBAE974A789968F22ECB1CBA7129FD2D524F0D4109DCA2E056483DDBC90FA159982AEB86F929E0D05188B4434C0AC1F071B6F431D08201E683F95CE6D2B4FA354E74F346144E52DB92A0F468ACCC0F8AE53C8BD1818CC577F65DE4188A6E2E10EB84FF9A31B04506E2E8ABD48FCA067B44348667922B7479EBFB9E6E5B8583C4AED84CEC8CCF3A3C3082A3519D2EE53917A09BBE4A52D1F8EA458F493D9D272B49529E6FD509A4EBC7E0927ADACF86C5C8BE31DE98EE65F3FA6CCDB9C308971118C68AF076C64A42745E9485C79AD78880C9DDD03D9529A71C4AE4D8A976C6461119E8CB44536420EDF4AC2499748F3078A1749E6FB4F8F8DCBE64962610695F1DB0BE4FE879A34D7A9BC94DAF492A9259C521F690EC1B00966F855C4B42C2D189B8AFDC34CFE3D49D974820287EE978495D640D80766C4CCA16D92117610A7DF97F444FC5B9B72C10BB8D632255C465F4128092C57B99426E4B0FD336BFC2455538E48FFCDC8CFFFC2064FFBC5FC0FA3CFC6A37140EBADEBF6C1F60C32F650C42988212D00CFFE0DB9D975F991A950D2D8C6B47676672EDB553FD8AA505E69BCCB9C89096FF1F5F5369F285EB8CE629FA7B56923824C3FFD7A2050471A4D90EC9DF24C22D9427267ACC6A13AABA1710B9469EE96E106468410866076B98D19B3E36F4CD052B89A35786D318FFE6EC0805E73A23E41C79B5287E0FC7618C2B4AA89CA27C8DEB5D016109ABEF7651589F4CBC413D3219945E35D243E8A6D3908735B01333F527C9CD10E5F0B2467C9F3623BCBC0008106B6732BD0CCABEBC331A463726BA783A8C036339D60B6B9AF8671D2AD57E07B6C445F23DD6B6FCF82F7B856FFCCC57A5C0B1D53F2E7930107B24009AB14883B20371E427A4FDBB0EFABB9B182071FF7BD4675D7CF47CFE9C17D9B9EFF98210EAF8D87638848AF6A6E1A5DE6AB975C96DE99352B534F639697EB6463F5F66A8613E24E462C92518A663725C023F18975A943FE89E9EF2C075F0FCA2AED88C2D61D0BCBE05629A88CA424A70B7EBEF17ADFC9005531FC01E2132C6AC685B36CCAF52DA039D0139E7E52E435374F4FF898005B84E75CACF730D262E66977FA18D5653538E9D7DF66B5684D7E3107E9F4A7A5EA5949A292D2CE9EB0B2AA76D737623614130364318DF1EBDE95676B507EF5CC76F08A8FB8A40CE93 +20240902012852 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D46ED77CB9B +20240902013705 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D46EDE42B6B +20240902022309 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D46F07C42B3 +20240902023700 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D46F13D6B9B +20240902033157 2 6 100 8191 5 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D46F444A467 +20240902074115 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D470264825B +20240902081217 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D47041D069B +20240902085634 2 6 100 8191 5 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D4706993BE7 +20240902095212 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D4709C080DB +20240902103310 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D470C00A7DB +20240902113925 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D470FB7C81B +20240902145636 2 6 100 8191 5 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D471ADD1BC7 +20240902162039 2 6 100 8191 5 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D471F910B07 +20240902162513 2 6 100 8191 5 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D471FCD9837 +20240902170958 2 6 100 8191 5 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D47224EBF47 +20240902195925 2 6 100 8191 5 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D472BED92A7 +20240902201041 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D472C8835C3 +20240902212334 2 6 100 8191 5 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D4730A0A15F +20240903001824 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D473A91EE3B +20240903003705 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D473B9B08CB +20240903010010 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D473CDEB7B3 +20240903010348 2 6 100 8191 5 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D473D0B3A67 +20240903034119 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D474614297B +20240903040728 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D4747910563 +20240903051146 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D474B45E3DB +20240903064823 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D4750BE2633 +20240903064907 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D4750C0835B +20240903101831 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D475C6B64DB +20240903113322 2 6 100 8191 5 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D4760A047BF +20240903122505 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D47638D75FB +20240903124220 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D476482E71B +20240903133142 2 6 100 8191 5 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D476752BA3F +20240903143834 2 6 100 8191 2 E90C219E279F374756F460D972C0503655CE6346FD0F611E8808CD4ADDDCE308981860661516592055313E99D7CC26BBCEE76FDE697801AA2827379287137910127F9107DEA68C3FAD7DBC9DADC15102DA2C4D890186E4279C8590E5D3F90E1B93EAFA540386086C4B55AE83AE5C7EB5FD9478B16F1143BB97202E24CE3FEE6E314B308A8CBC1F2938D7013654B6A5D141D4422375EDDEA2C2011231C5C83F318FCBE6A8FBEA20D8E9C2618D45DEBE36611557447900B4B8248A25E4D523C3D9DCAB1F1C1A7CE5EFD7FA4B1BF34486F5737F61A94C20D9268CCC52785FBF8CE06D605997A8DE54E76D7F566582C8C064E244151FD43E7B97368891F274FF1D1EBB9627BEBE9B9B202E656445873198D32286D9D8F9F0387D3ABC6C0C74C9FEC8FA935C5F43287AA191591A6ADF80EBD6EB5B58C2524BE2E2E3000A25345A7D082B7AD136133E87B4BFED4C20EE58055EDA6E9D2E2F15E299D14E11919F2C3029CE1C818D5D30EA68D0458F3B1AB30923F55F84A3BCF14137B547D56CA353F3BB7EC6F22705CC0B14FBD8D7E869325B688AA759C30FAFC74A01567BD785F4ED1F0ED1B7B82F00467A687EC3BB12A246B620B2FE0B9783C222F999CCB7CEF6FA2E3FE4DE652FC0C4B21FC4DF2CEF7981F644FB2158B208C71C68C6974D4D1090C830379707BC30C7748487EB922A4B40CB0FE33B5B4A8E22354ADB2020315D043706D608B1213A2974ED5CC6EA8A520E3147667DD81F4294313AF935C528C82B659B7A169F4B11CD03A3D35546A4E4E2FF79DB6173F3A762B22EBE4BE5B49DD4951A6BC27D5EDD8486E2105561B9BE23F1826BC0579A482AFFD99508E09F17A20419F56A31AEFADCBF816706BC1B47420A7C66A19AF1A725D691CED949F9135404B35237E6B07A037F87F4515B7F1FD5B2A7B3B562ED121A12C1B4BF9E408A0221922B10B78B9D75B81381853BBF734BBE33E12602D4191BCD47B57FA20803F1D75FD4D5A077D50DD537A6B38AB09A1A3C1B30845A0D92AA38BD1B7D1F1AA1AC9FE9CD0A0DE23BD1943A99793D18FC08BD9D7744B62D460263F879087A996FC2868675FE43F7026C6C3C93187C629AF58038F61E3072D8A4B42ABFD1639C5F2289E0A974FFBBC67FD2BAC657BC3C582664A6AD8B940E8F8596FDB8B6429C1A1F06AB1249C9A03F271F66550503E9613277D38DC63031F21AA7C8C9B2D91D6F6B7C036BAB18B5FC8900E4679992DE4BAA2CF202787D521D1545AF4A090E8E17F7E8012C104791D2F6025A41C543F9D85C1DD3EE5757CA2445697075C87D0334FD0F5C9AA8EAFF4A8A4AAEDBE7F2C80151066C7A0F05B3A6B6E5EFD1DE7FE9C53421A00BA9917C732D4735ECEE42CDE994FA6DE2C171207B2A4ADE76EC4411C2171F7C7A0E05C37E3BE842F224A3F8FF6A55DC806FC3F7904147910B6D476B1AC6BB diff --git a/moduli.0 b/moduli.0 index 057a018efe3..f72ca524964 100644 --- a/moduli.0 +++ b/moduli.0 @@ -71,4 +71,4 @@ STANDARDS M. Friedl, N. Provos, and W. Simpson, Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, March 2006. -OpenBSD 7.5 April 16, 2022 OpenBSD 7.5 +OpenBSD 7.6 April 16, 2022 OpenBSD 7.6 diff --git a/monitor.c b/monitor.c index 1f45aef7679..56a796ff48b 100644 --- a/monitor.c +++ b/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.240 2024/06/06 17:15:25 djm Exp $ */ +/* $OpenBSD: monitor.c,v 1.247 2024/12/03 22:30:03 jsg Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -97,6 +97,7 @@ #include "match.h" #include "ssherr.h" #include "sk-api.h" +#include "srclimit.h" #ifdef GSSAPI static Gssctxt *gsscontext = NULL; @@ -105,7 +106,9 @@ static Gssctxt *gsscontext = NULL; /* Imports */ extern ServerOptions options; extern u_int utmp_len; +extern struct sshbuf *cfg; extern struct sshbuf *loginmsg; +extern struct include_list includes; extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ /* State exported from the child */ @@ -126,6 +129,7 @@ int mm_answer_keyverify(struct ssh *, int, struct sshbuf *); int mm_answer_pty(struct ssh *, int, struct sshbuf *); int mm_answer_pty_cleanup(struct ssh *, int, struct sshbuf *); int mm_answer_term(struct ssh *, int, struct sshbuf *); +int mm_answer_state(struct ssh *, int, struct sshbuf *); #ifdef USE_PAM int mm_answer_pam_start(struct ssh *, int, struct sshbuf *); @@ -188,6 +192,7 @@ static int monitor_read(struct ssh *, struct monitor *, struct mon_table *, static int monitor_read_log(struct monitor *); struct mon_table mon_dispatch_proto20[] = { + {MONITOR_REQ_STATE, MON_ONCE, mm_answer_state}, #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, #endif @@ -223,6 +228,7 @@ struct mon_table mon_dispatch_proto20[] = { }; struct mon_table mon_dispatch_postauth20[] = { + {MONITOR_REQ_STATE, MON_ONCE, mm_answer_state}, #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif @@ -288,7 +294,8 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) authctxt->loginmsg = loginmsg; mon_dispatch = mon_dispatch_proto20; - /* Permit requests for moduli and signatures */ + /* Permit requests for state, moduli and signatures */ + monitor_permit(mon_dispatch, MONITOR_REQ_STATE, 1); monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -409,6 +416,7 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) mon_dispatch = mon_dispatch_postauth20; /* Permit requests for moduli and signatures */ + monitor_permit(mon_dispatch, MONITOR_REQ_STATE, 1); monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -463,7 +471,7 @@ monitor_read_log(struct monitor *pmonitor) (r = sshbuf_get_u32(logmsg, &forced)) != 0 || (r = sshbuf_get_cstring(logmsg, &msg, NULL)) != 0) fatal_fr(r, "parse"); - + if (log_level_name(level) == NULL) fatal_f("invalid log level %u (corrupted message?)", level); @@ -482,19 +490,20 @@ monitor_read_log(struct monitor *pmonitor) } /*log it*/ - if (authctxt->authenticated == 0) + if (authctxt->authenticated == 0) sshlogdirect(level, forced, "user: %s: %s [preauth]", authctxt->user, msg); else { if (strcmp(pname, "sftp-server") == 0) { log_init(pname, sftp_log_level, sftp_log_facility, sftp_log_stderr); - sshlogdirect(level, forced, "user: %s: %s", authctxt->user, msg); + sshlogdirect(level, forced, "user: %s: %s [postauth]", authctxt->user, msg); log_init("sshd", options.log_level, options.log_facility, log_stderr); - } else - sshlogdirect(level, forced, "user: %s: %s", authctxt->user, msg); + } else + sshlogdirect(level, forced, "user: %s: %s [postauth]", authctxt->user, msg); } #else /*log it*/ - sshlogdirect(level, forced, "%s [preauth]", msg); + sshlogdirect(level, forced, "%s [%s]", msg, + mon_dispatch == mon_dispatch_postauth20 ? "postauth" : "preauth"); #endif sshbuf_free(logmsg); @@ -601,6 +610,82 @@ monitor_reset_key_state(void) hostbased_chost = NULL; } +int +mm_answer_state(struct ssh *ssh, int sock, struct sshbuf *m) +{ + struct sshbuf *inc = NULL, *hostkeys = NULL; + struct sshbuf *opts = NULL, *confdata = NULL; + struct include_item *item = NULL; + int postauth; + int r; + + sshbuf_reset(m); + + debug_f("config len %zu", sshbuf_len(cfg)); + + if ((m = sshbuf_new()) == NULL || + (inc = sshbuf_new()) == NULL || + (opts = sshbuf_new()) == NULL || + (confdata = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + + /* XXX unnecessary? */ + /* pack includes into a string */ + TAILQ_FOREACH(item, &includes, entry) { + if ((r = sshbuf_put_cstring(inc, item->selector)) != 0 || + (r = sshbuf_put_cstring(inc, item->filename)) != 0 || + (r = sshbuf_put_stringb(inc, item->contents)) != 0) + fatal_fr(r, "compose includes"); + } + + hostkeys = pack_hostkeys(); + + /* + * Protocol from monitor to unpriv privsep process: + * string configuration + * uint64 timing_secret XXX move delays to monitor and remove + * string host_keys[] { + * string public_key + * string certificate + * } + * string server_banner + * string client_banner + * string included_files[] { + * string selector + * string filename + * string contents + * } + * string configuration_data (postauth) + * string keystate (postauth) + * string authenticated_user (postauth) + * string session_info (postauth) + * string authopts (postauth) + */ + if ((r = sshbuf_put_stringb(m, cfg)) != 0 || + (r = sshbuf_put_u64(m, options.timing_secret)) != 0 || + (r = sshbuf_put_stringb(m, hostkeys)) != 0 || + (r = sshbuf_put_stringb(m, ssh->kex->server_version)) != 0 || + (r = sshbuf_put_stringb(m, ssh->kex->client_version)) != 0 || + (r = sshbuf_put_stringb(m, inc)) != 0) + fatal_fr(r, "compose config"); + + postauth = (authctxt && authctxt->pw && authctxt->authenticated); + if (postauth) { + /* XXX shouldn't be reachable */ + fatal_f("internal error: called in postauth"); + } + + sshbuf_free(inc); + sshbuf_free(opts); + sshbuf_free(confdata); + + mm_request_send(sock, MONITOR_ANS_STATE, m); + + debug3_f("done"); + + return (0); +} + #ifdef WITH_OPENSSL int mm_answer_moduli(struct ssh *ssh, int sock, struct sshbuf *m) @@ -646,24 +731,27 @@ int mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) { extern int auth_sock; /* XXX move to state struct? */ - struct sshkey *key; + struct sshkey *pubkey, *key; struct sshbuf *sigbuf = NULL; u_char *p = NULL, *signature = NULL; char *alg = NULL; - size_t datlen, siglen, alglen; - int r, is_proof = 0; - u_int keyid, compat; + size_t datlen, siglen; + int r, is_proof = 0, keyid; + u_int compat; const char proof_req[] = "hostkeys-prove-00@openssh.com"; debug3_f("entering"); - if ((r = sshbuf_get_u32(m, &keyid)) != 0 || + if ((r = sshkey_froms(m, &pubkey)) != 0 || (r = sshbuf_get_string(m, &p, &datlen)) != 0 || - (r = sshbuf_get_cstring(m, &alg, &alglen)) != 0 || + (r = sshbuf_get_cstring(m, &alg, NULL)) != 0 || (r = sshbuf_get_u32(m, &compat)) != 0) fatal_fr(r, "parse"); - if (keyid > INT_MAX) - fatal_f("invalid key ID"); + + if ((keyid = get_hostkey_index(pubkey, 1, ssh)) == -1) + fatal_f("unknown hostkey"); + debug_f("hostkey %s index %d", sshkey_ssh_name(pubkey), keyid); + sshkey_free(pubkey); /* * Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes), @@ -831,6 +919,15 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) ssh_packet_set_log_preamble(ssh, "%suser %s", authctxt->valid ? "authenticating" : "invalid ", authctxt->user); + if (options.refuse_connection) { + logit("administratively prohibited connection for " + "%s%s from %.128s port %d", + authctxt->valid ? "" : "invalid user ", + authctxt->user, ssh_remote_ipaddr(ssh), + ssh_remote_port(ssh)); + cleanup_exit(EXIT_CONFIG_REFUSED); + } + /* Send active options to unpriv */ mm_encode_server_options(m); @@ -1530,7 +1627,7 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) } auth2_record_key(authctxt, ret == 0, key); - if (key_blobtype == MM_USERKEY) + if (key_blobtype == MM_USERKEY && ret == 0) auth_activate_options(ssh, key_opts); monitor_reset_key_state(); @@ -1772,7 +1869,7 @@ monitor_send_keystate(struct monitor *pmonitor) { sshbuf_free(m); } -void +void monitor_recv_keystate(struct monitor*pmonitor) { struct sshbuf *m; u_char *cp, ver; @@ -1820,7 +1917,7 @@ monitor_send_authopt(struct monitor *pmonitor, int untrusted) { if ((m = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); - + if (auth_opts != NULL && (r = sshauthopt_serialise(auth_opts, m, untrusted)) != 0) fatal("%s: sshauthopt_serialise: %s", __func__, ssh_err(r)); @@ -1850,7 +1947,7 @@ monitor_recv_authopt(struct monitor*pmonitor) { if ((r = sshauthopt_deserialise(m, &auth_opts)) != 0) fatal("%s: sshauthopt_deserialise: %s", __func__, ssh_err(r)); - + debug3("%s: done", __func__); sshbuf_free(m); } @@ -1892,6 +1989,7 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; + kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; kex->load_host_public_key=&get_hostkey_public_by_type; kex->load_host_private_key=&get_hostkey_private_by_type; kex->host_key_index=&get_hostkey_index; @@ -1952,8 +2050,6 @@ monitor_openfds(struct monitor *mon, int do_logfds) mon->m_log_recvfd = mon->m_log_sendfd = -1; } -#define MM_MEMSIZE 65536 - struct monitor * monitor_init(void) { diff --git a/monitor.h b/monitor.h index da881bebce2..63592b2c371 100644 --- a/monitor.h +++ b/monitor.h @@ -54,6 +54,7 @@ enum monitor_reqtype { MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47, MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49, MONITOR_REQ_TERM = 50, + MONITOR_REQ_STATE = 51, MONITOR_ANS_STATE = 52, MONITOR_REQ_PAM_START = 100, MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103, @@ -98,4 +99,6 @@ void mm_get_keystate(struct ssh *, struct monitor *); /* XXX: should be returned via a monitor call rather than config_fd */ void mm_encode_server_options(struct sshbuf *); +struct sshbuf *pack_hostkeys(void); + #endif /* _MONITOR_H_ */ diff --git a/monitor_wrap.c b/monitor_wrap.c index 56b8ddbb18f..c237f0c4016 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.136 2024/06/19 23:24:47 djm Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.138 2024/10/22 06:13:00 dtucker Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -124,16 +124,6 @@ mm_log_handler(LogLevel level, int forced, const char *msg, void *ctx) sshbuf_free(log_msg); } -int -mm_is_monitor(void) -{ - /* - * m_pid is only set in the privileged part, and - * points to the unprivileged child. - */ - return (pmonitor && pmonitor->m_pid > 0); -} - static void mm_reap(void) { @@ -277,15 +267,13 @@ mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp, const u_char *data, size_t datalen, const char *hostkey_alg, const char *sk_provider, const char *sk_pin, u_int compat) { - struct kex *kex = *pmonitor->m_pkex; struct sshbuf *m; - u_int ndx = kex->host_key_index(key, 0, ssh); int r; debug3_f("entering"); if ((m = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); - if ((r = sshbuf_put_u32(m, ndx)) != 0 || + if ((r = sshkey_puts(key, m)) != 0 || (r = sshbuf_put_string(m, data, datalen)) != 0 || (r = sshbuf_put_cstring(m, hostkey_alg)) != 0 || (r = sshbuf_put_u32(m, compat)) != 0) @@ -298,6 +286,8 @@ mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp, if ((r = sshbuf_get_string(m, sigp, lenp)) != 0) fatal_fr(r, "parse"); sshbuf_free(m); + debug3_f("%s signature len=%zu", hostkey_alg ? hostkey_alg : "(null)", + *lenp); return (0); } @@ -874,6 +864,72 @@ mm_terminate(void) sshbuf_free(m); } +/* Request state information */ + +void +mm_get_state(struct ssh *ssh, struct include_list *includes, + struct sshbuf *conf, struct sshbuf **confdatap, + uint64_t *timing_secretp, + struct sshbuf **hostkeysp, struct sshbuf **keystatep, + u_char **pw_namep, + struct sshbuf **authinfop, struct sshbuf **auth_optsp) +{ + struct sshbuf *m, *inc; + u_char *cp; + size_t len; + int r; + struct include_item *item; + + debug3_f("entering"); + + if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_STATE, m); + + debug3_f("waiting for MONITOR_ANS_STATE"); + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_STATE, m); + + if ((r = sshbuf_get_string(m, &cp, &len)) != 0 || + (r = sshbuf_get_u64(m, timing_secretp)) != 0 || + (r = sshbuf_froms(m, hostkeysp)) != 0 || + (r = sshbuf_get_stringb(m, ssh->kex->server_version)) != 0 || + (r = sshbuf_get_stringb(m, ssh->kex->client_version)) != 0 || + (r = sshbuf_get_stringb(m, inc)) != 0) + fatal_fr(r, "parse config"); + + /* postauth */ + if (confdatap) { + if ((r = sshbuf_froms(m, confdatap)) != 0 || + (r = sshbuf_froms(m, keystatep)) != 0 || + (r = sshbuf_get_string(m, pw_namep, NULL)) != 0 || + (r = sshbuf_froms(m, authinfop)) != 0 || + (r = sshbuf_froms(m, auth_optsp)) != 0) + fatal_fr(r, "parse config postauth"); + } + + if (conf != NULL && (r = sshbuf_put(conf, cp, len))) + fatal_fr(r, "sshbuf_put"); + + while (sshbuf_len(inc) != 0) { + item = xcalloc(1, sizeof(*item)); + if ((item->contents = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshbuf_get_cstring(inc, &item->selector, NULL)) != 0 || + (r = sshbuf_get_cstring(inc, &item->filename, NULL)) != 0 || + (r = sshbuf_get_stringb(inc, item->contents)) != 0) + fatal_fr(r, "parse includes"); + TAILQ_INSERT_TAIL(includes, item, entry); + } + + free(cp); + sshbuf_free(m); + sshbuf_free(inc); + + debug3_f("done"); +} + static void mm_chall_setup(char **name, char **infotxt, u_int *numprompts, char ***prompts, u_int **echo_on) diff --git a/monitor_wrap.h b/monitor_wrap.h index e768036ed43..7134afeecf4 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -90,6 +90,12 @@ void mm_session_pty_cleanup2(struct Session *); void mm_send_keystate(struct ssh *, struct monitor*); +/* state */ +struct include_list; +void mm_get_state(struct ssh *, struct include_list *, struct sshbuf *, + struct sshbuf **, uint64_t *, struct sshbuf **, struct sshbuf **, + u_char **, struct sshbuf **, struct sshbuf **); + /* bsdauth */ int mm_bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_bsdauth_respond(void *, u_int, char **); diff --git a/mux.c b/mux.c index d598a17e2da..415024f74e8 100644 --- a/mux.c +++ b/mux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mux.c,v 1.101 2023/11/23 03:37:05 dtucker Exp $ */ +/* $OpenBSD: mux.c,v 1.103 2024/10/12 10:50:37 jsg Exp $ */ /* * Copyright (c) 2002-2008 Damien Miller * @@ -68,7 +68,6 @@ #include "readconf.h" #include "clientloop.h" #include "ssherr.h" -#include "misc.h" /* from ssh.c */ extern int tty_flag; @@ -201,8 +200,8 @@ mux_master_session_cleanup_cb(struct ssh *ssh, int cid, int force, void *unused) fatal_f("channel %d missing control channel %d", c->self, c->ctl_chan); c->ctl_chan = -1; - cc->remote_id = 0; - cc->have_remote_id = 0; + cc->ctl_child_id = 0; + cc->have_ctl_child_id = 0; chan_rcvd_oclose(ssh, cc); } channel_cancel_cleanup(ssh, c->self); @@ -217,12 +216,12 @@ mux_master_control_cleanup_cb(struct ssh *ssh, int cid, int force, void *unused) debug3_f("entering for channel %d", cid); if (c == NULL) fatal_f("channel_by_id(%i) == NULL", cid); - if (c->have_remote_id) { - if ((sc = channel_by_id(ssh, c->remote_id)) == NULL) + if (c->have_ctl_child_id) { + if ((sc = channel_by_id(ssh, c->ctl_child_id)) == NULL) fatal_f("channel %d missing session channel %u", - c->self, c->remote_id); - c->remote_id = 0; - c->have_remote_id = 0; + c->self, c->ctl_child_id); + c->ctl_child_id = 0; + c->have_ctl_child_id = 0; sc->ctl_chan = -1; if (sc->type != SSH_CHANNEL_OPEN && sc->type != SSH_CHANNEL_OPENING) { @@ -418,7 +417,7 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid, new_fd[0], new_fd[1], new_fd[2]); /* XXX support multiple child sessions in future */ - if (c->have_remote_id) { + if (c->have_ctl_child_id) { debug2_f("session already open"); reply_error(reply, MUX_S_FAILURE, rid, "Multiple sessions not supported"); @@ -463,8 +462,8 @@ mux_master_process_new_session(struct ssh *ssh, u_int rid, CHAN_EXTENDED_WRITE, "client-session", CHANNEL_NONBLOCK_STDIO); nc->ctl_chan = c->self; /* link session -> control channel */ - c->remote_id = nc->self; /* link control -> session channel */ - c->have_remote_id = 1; + c->ctl_child_id = nc->self; /* link control -> session channel */ + c->have_ctl_child_id = 1; if (cctx->want_tty && escape_char != 0xffffffff) { channel_register_filter(ssh, nc->self, @@ -1003,7 +1002,7 @@ mux_master_process_stdio_fwd(struct ssh *ssh, u_int rid, debug3_f("got fds stdin %d, stdout %d", new_fd[0], new_fd[1]); /* XXX support multiple child sessions in future */ - if (c->have_remote_id) { + if (c->have_ctl_child_id) { debug2_f("session already open"); reply_error(reply, MUX_S_FAILURE, rid, "Multiple sessions not supported"); @@ -1035,8 +1034,8 @@ mux_master_process_stdio_fwd(struct ssh *ssh, u_int rid, free(chost); nc->ctl_chan = c->self; /* link session -> control channel */ - c->remote_id = nc->self; /* link control -> session channel */ - c->have_remote_id = 1; + c->ctl_child_id = nc->self; /* link control -> session channel */ + c->have_ctl_child_id = 1; debug2_f("channel_new: %d control %d", nc->self, nc->ctl_chan); diff --git a/myproposal.h b/myproposal.h index 57ae9dedfb6..cbc40d026fc 100644 --- a/myproposal.h +++ b/myproposal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.71 2022/03/30 21:13:23 djm Exp $ */ +/* $OpenBSD: myproposal.h,v 1.77 2024/12/02 14:06:42 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -31,26 +31,24 @@ "curve25519-sha256@libssh.org," \ "ecdh-sha2-nistp256," \ "ecdh-sha2-nistp384," \ - "ecdh-sha2-nistp521," \ - "diffie-hellman-group-exchange-sha256," \ - "diffie-hellman-group16-sha512," \ - "diffie-hellman-group18-sha512," \ - "diffie-hellman-group14-sha256" + "ecdh-sha2-nistp521," #else #define KEX_SERVER_KEX \ + "mlkem768x25519-sha256," \ + "sntrup761x25519-sha512," \ "sntrup761x25519-sha512@openssh.com," \ "curve25519-sha256," \ "curve25519-sha256@libssh.org," \ "ecdh-sha2-nistp256," \ "ecdh-sha2-nistp384," \ - "ecdh-sha2-nistp521," \ + "ecdh-sha2-nistp521" +#endif + +#define KEX_CLIENT_KEX KEX_SERVER_KEX "," \ "diffie-hellman-group-exchange-sha256," \ "diffie-hellman-group16-sha512," \ "diffie-hellman-group18-sha512," \ "diffie-hellman-group14-sha256" -#endif - -#define KEX_CLIENT_KEX KEX_SERVER_KEX #define KEX_DEFAULT_PK_ALG \ "ssh-ed25519-cert-v01@openssh.com," \ @@ -72,8 +70,8 @@ #define KEX_SERVER_ENCRYPT \ "chacha20-poly1305@openssh.com," \ - "aes128-ctr,aes192-ctr,aes256-ctr," \ - "aes128-gcm@openssh.com,aes256-gcm@openssh.com" + "aes128-gcm@openssh.com,aes256-gcm@openssh.com," \ + "aes128-ctr,aes192-ctr,aes256-ctr" #define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT diff --git a/nchan.c b/nchan.c index b156695b27b..bd4758ac120 100644 --- a/nchan.c +++ b/nchan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nchan.c,v 1.75 2024/02/01 02:37:33 djm Exp $ */ +/* $OpenBSD: nchan.c,v 1.76 2024/07/25 22:40:08 djm Exp $ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -208,7 +208,7 @@ chan_send_close2(struct ssh *ssh, Channel *c) { int r; - debug2("channel %d: send close", c->self); + debug2("channel %d: send_close2", c->self); if (c->ostate != CHAN_OUTPUT_CLOSED || c->istate != CHAN_INPUT_CLOSED) { error("channel %d: cannot send close for istate/ostate %d/%d", @@ -218,6 +218,8 @@ chan_send_close2(struct ssh *ssh, Channel *c) } else { if (!c->have_remote_id) fatal_f("channel %d: no remote_id", c->self); + debug2("channel %d: send close for remote id %u", c->self, + c->remote_id); if ((r = sshpkt_start(ssh, SSH2_MSG_CHANNEL_CLOSE)) != 0 || (r = sshpkt_put_u32(ssh, c->remote_id)) != 0 || (r = sshpkt_send(ssh)) != 0) diff --git a/openbsd-compat/arc4random.h b/openbsd-compat/arc4random.h index 5af3a4492a8..af2d5c172a2 100644 --- a/openbsd-compat/arc4random.h +++ b/openbsd-compat/arc4random.h @@ -23,7 +23,9 @@ * Stub functions for portability. From LibreSSL with some adaptations. */ +#ifdef HAVE_SYS_MMAN_H #include +#endif #include diff --git a/openbsd-compat/bsd-pselect.c b/openbsd-compat/bsd-pselect.c index 7866729bb01..7508e5c25db 100644 --- a/openbsd-compat/bsd-pselect.c +++ b/openbsd-compat/bsd-pselect.c @@ -40,75 +40,47 @@ #include #include "log.h" -#include "misc.h" /* for set_nonblock */ #ifndef HAVE_SIGHANDLER_T typedef void (*sighandler_t)(int); #endif static sighandler_t saved_sighandler[_NSIG]; +static int notify_pipe[2]; /* 0 = read end, 1 = write end */ /* - * Set up the descriptors. Because they are close-on-exec, in the case - * where sshd's re-exec fails notify_pipe will still point to a descriptor - * that was closed by the exec attempt but if that descriptor has been - * reopened then we'll attempt to use that. Ensure that notify_pipe is - * outside of the range used by sshd re-exec but within NFDBITS (so we don't - * need to expand the fd_sets). + * Because the debugging for this is so noisy, we only output on the first + * call, and suppress it thereafter. */ -#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) -static int -pselect_notify_setup_fd(int *fd) +static int suppress_debug; + +static void +pselect_set_nonblock(int fd) { - int r; + int val; - if ((r = fcntl(*fd, F_DUPFD, REEXEC_MIN_FREE_FD)) < 0 || - fcntl(r, F_SETFD, FD_CLOEXEC) < 0 || r >= FD_SETSIZE) - return -1; - (void)close(*fd); - return (*fd = r); + if ((val = fcntl(fd, F_GETFL)) == -1 || + fcntl(fd, F_SETFL, val|O_NONBLOCK) == -1) + error_f("fcntl: %s", strerror(errno)); } /* * we write to this pipe if a SIGCHLD is caught in order to avoid - * the race between select() and child_terminated + * the race between select() and child_terminated. */ -static pid_t notify_pid; -static int notify_pipe[2]; -static void +static int pselect_notify_setup(void) { - static int initialized; - - if (initialized && notify_pid == getpid()) - return; - if (notify_pid == 0) - debug3_f("initializing"); - else { - debug3_f("pid changed, reinitializing"); - if (notify_pipe[0] != -1) - close(notify_pipe[0]); - if (notify_pipe[1] != -1) - close(notify_pipe[1]); - } if (pipe(notify_pipe) == -1) { error("pipe(notify_pipe) failed %s", strerror(errno)); - } else if (pselect_notify_setup_fd(¬ify_pipe[0]) == -1 || - pselect_notify_setup_fd(¬ify_pipe[1]) == -1) { - error("fcntl(notify_pipe, ...) failed %s", strerror(errno)); - close(notify_pipe[0]); - close(notify_pipe[1]); - } else { - set_nonblock(notify_pipe[0]); - set_nonblock(notify_pipe[1]); - notify_pid = getpid(); - debug3_f("pid %d saved %d pipe0 %d pipe1 %d", getpid(), - notify_pid, notify_pipe[0], notify_pipe[1]); - initialized = 1; - return; + notify_pipe[0] = notify_pipe[1] = -1; + return -1; } - notify_pipe[0] = -1; /* read end */ - notify_pipe[1] = -1; /* write end */ + pselect_set_nonblock(notify_pipe[0]); + pselect_set_nonblock(notify_pipe[1]); + if (!suppress_debug) + debug3_f("pipe0 %d pipe1 %d", notify_pipe[0], notify_pipe[1]); + return 0; } static void pselect_notify_parent(void) @@ -132,6 +104,8 @@ pselect_notify_done(fd_set *readset) debug2_f("reading"); FD_CLR(notify_pipe[0], readset); } + (void)close(notify_pipe[0]); + (void)close(notify_pipe[1]); } /*ARGSUSED*/ @@ -167,26 +141,29 @@ pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, if (mask == NULL) /* no signal mask, just call select */ return select(nfds, readfds, writefds, exceptfds, tvp); - /* For each signal we're unmasking, install our handler if needed. */ + /* For each signal unmasked, save old handler and install ours. */ for (sig = 0; sig < _NSIG; sig++) { + saved_sighandler[sig] = NULL; if (sig == SIGKILL || sig == SIGSTOP || sigismember(mask, sig)) continue; if (sigaction(sig, NULL, &sa) == 0 && sa.sa_handler != SIG_IGN && sa.sa_handler != SIG_DFL) { unmasked = 1; - if (sa.sa_handler == pselect_sig_handler) - continue; sa.sa_handler = pselect_sig_handler; if (sigaction(sig, &sa, &osa) == 0) { - debug3_f("installing signal handler for %s, " - "previous %p", strsignal(sig), - osa.sa_handler); + if (!suppress_debug) + debug3_f("installed signal handler for" + " %s, previous 0x%p", + strsignal(sig), osa.sa_handler); saved_sighandler[sig] = osa.sa_handler; } } } if (unmasked) { - pselect_notify_setup(); + if ((ret = pselect_notify_setup()) == -1) { + saved_errno = ENOMEM; + goto out; + } pselect_notify_prepare(readfds); nfds = MAX(nfds, notify_pipe[0] + 1); } @@ -199,6 +176,25 @@ pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, if (unmasked) pselect_notify_done(readfds); + + out: + /* Restore signal handlers. */ + for (sig = 0; sig < _NSIG; sig++) { + if (saved_sighandler[sig] == NULL) + continue; + if (sigaction(sig, NULL, &sa) == 0) { + sa.sa_handler = saved_sighandler[sig]; + if (sigaction(sig, &sa, NULL) == 0) { + if (!suppress_debug) + debug3_f("restored signal handler for " + "%s", strsignal(sig)); + } else { + error_f("failed to restore signal handler for " + "%s: %s", strsignal(sig), strerror(errno)); + } + } + } + suppress_debug = 1; errno = saved_errno; return ret; diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index 6c65003f2b3..14865077e46 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c @@ -95,4 +95,30 @@ ssh_libcrypto_init(void) #endif /* USE_OPENSSL_ENGINE */ } +#ifndef HAVE_EVP_DIGESTSIGN +int +EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen, + const unsigned char *tbs, size_t tbslen) +{ + if (sigret != NULL) { + if (EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0) + return 0; + } + + return EVP_DigestSignFinal(ctx, sigret, siglen); +} +#endif + +#ifndef HAVE_EVP_DIGESTVERIFY +int +EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0) + return -1; + + return EVP_DigestVerifyFinal(ctx, sigret, siglen); +} +#endif + #endif /* WITH_OPENSSL */ diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index f6796b3baaa..6b8fff41295 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -55,9 +55,9 @@ void ssh_libcrypto_init(void); # endif #endif -#ifdef OPENSSL_IS_BORINGSSL +#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC) /* - * BoringSSL (rightly) got rid of the BN_FLG_CONSTTIME flag, along with + * BoringSSL and AWS-LC (rightly) got rid of the BN_FLG_CONSTTIME flag, along with * the entire BN_set_flags() interface. * https://boringssl.googlesource.com/boringssl/+/0a211dfe9 */ @@ -78,5 +78,15 @@ int EVP_CIPHER_CTX_set_iv(EVP_CIPHER_CTX *ctx, const unsigned char *iv, size_t len); #endif /* HAVE_EVP_CIPHER_CTX_SET_IV */ +#ifndef HAVE_EVP_DIGESTSIGN +int EVP_DigestSign(EVP_MD_CTX *, unsigned char *, size_t *, + const unsigned char *, size_t); +#endif + +#ifndef HAVE_EVP_DIGESTVERIFY +int EVP_DigestVerify(EVP_MD_CTX *, const unsigned char *, size_t, + const unsigned char *, size_t); +#endif + #endif /* WITH_OPENSSL */ #endif /* _OPENSSL_COMPAT_H */ diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index 8adfec5a7a8..c1d54f38d65 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c @@ -319,6 +319,19 @@ oom_adjust_restore(void) } #endif /* LINUX_OOM_ADJUST */ +#ifdef LINUX_MEMLOCK_ONFAULT +#include + +void +memlock_onfault_setup(void) +{ + if (mlockall(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT) < 0) + verbose("unable to lock memory: %s", strerror(errno)); + else + debug("memory locked"); +} +#endif /* LINUX_MEMLOCK_ONFAULT */ + #ifdef SYSTEMD_NOTIFY static void ssh_systemd_notify(const char *, ...) diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index 14064f87db8..959430de136 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h @@ -30,6 +30,10 @@ void oom_adjust_restore(void); void oom_adjust_setup(void); #endif +#ifdef LINUX_MEMLOCK_ONFAULT +void memlock_onfault_setup(void); +#endif + #ifdef SYSTEMD_NOTIFY void ssh_systemd_notify_ready(void); void ssh_systemd_notify_reload(void); diff --git a/packet.c b/packet.c index d8fb4c56375..75268bad3ac 100644 --- a/packet.c +++ b/packet.c @@ -1015,9 +1015,8 @@ ssh_set_newkeys(struct ssh *ssh, int mode) /* explicit_bzero(enc->iv, enc->block_size); explicit_bzero(enc->key, enc->key_len); explicit_bzero(mac->key, mac->key_len); */ - if ((comp->type == COMP_ZLIB || - (comp->type == COMP_DELAYED && - state->after_authentication)) && comp->enabled == 0) { + if (((comp->type == COMP_DELAYED && state->after_authentication)) && + comp->enabled == 0) { if ((r = ssh_packet_init_compression(ssh)) < 0) return r; if (mode == MODE_OUT) { @@ -2647,12 +2646,6 @@ sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v) return sshbuf_put_stringb(ssh->state->outgoing_packet, v); } -int -sshpkt_getb_froms(struct ssh *ssh, struct sshbuf **valp) -{ - return sshbuf_froms(ssh->state->incoming_packet, valp); -} - #ifdef WITH_OPENSSL #ifdef OPENSSL_HAS_ECC int @@ -2660,8 +2653,13 @@ sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g) { return sshbuf_put_ec(ssh->state->outgoing_packet, v, g); } -#endif /* OPENSSL_HAS_ECC */ +int +sshpkt_put_ec_pkey(struct ssh *ssh, EVP_PKEY *pkey) +{ + return sshbuf_put_ec_pkey(ssh->state->outgoing_packet, pkey); +} +#endif /* OPENSSL_HAS_ECC */ int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v) @@ -2720,6 +2718,12 @@ sshpkt_get_cstring(struct ssh *ssh, char **valp, size_t *lenp) return sshbuf_get_cstring(ssh->state->incoming_packet, valp, lenp); } +int +sshpkt_getb_froms(struct ssh *ssh, struct sshbuf **valp) +{ + return sshbuf_froms(ssh->state->incoming_packet, valp); +} + #ifdef WITH_OPENSSL #ifdef OPENSSL_HAS_ECC int diff --git a/packet.h b/packet.h index 5ab1f409a2c..49bb87f0750 100644 --- a/packet.h +++ b/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.98 2024/05/17 06:42:04 jsg Exp $ */ +/* $OpenBSD: packet.h,v 1.99 2024/08/15 00:51:51 djm Exp $ */ /* * Author: Tatu Ylonen @@ -20,6 +20,7 @@ #ifdef WITH_OPENSSL # include +# include # ifdef OPENSSL_HAS_ECC # include # else /* OPENSSL_HAS_ECC */ @@ -32,6 +33,7 @@ # define EC_KEY void # define EC_GROUP void # define EC_POINT void +# define EVP_PKEY void #endif /* WITH_OPENSSL */ #include @@ -191,6 +193,7 @@ int sshpkt_put_string(struct ssh *ssh, const void *v, size_t len); int sshpkt_put_cstring(struct ssh *ssh, const void *v); int sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v); int sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g); +int sshpkt_put_ec_pkey(struct ssh *ssh, EVP_PKEY *pkey); int sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v); int sshpkt_get(struct ssh *ssh, void *valp, size_t len); @@ -213,6 +216,7 @@ const u_char *sshpkt_ptr(struct ssh *, size_t *lenp); # undef EC_KEY # undef EC_GROUP # undef EC_POINT +# undef EVP_PKEY #elif !defined(OPENSSL_HAS_ECC) # undef EC_KEY # undef EC_GROUP diff --git a/pathnames.h b/pathnames.h index d772e903e96..3b5b5aa9bef 100644 --- a/pathnames.h +++ b/pathnames.h @@ -55,6 +55,13 @@ #define _PATH_SSHD_SESSION "/usr/libexec/sshd-session" #endif /* WINDOWS */ #endif +#ifndef _PATH_SSHD_AUTH +#ifdef WINDOWS +#define _PATH_SSHD_AUTH "sshd-auth.exe" /* PATH looks in same directory as sshd automatically */ +#else /* WINDOWS */ +#define _PATH_SSHD_AUTH "/usr/libexec/sshd-auth" +#endif /* WINDOWS */ +#endif /* * The process id of the daemon listening for connections is saved here to diff --git a/platform-listen.c b/platform-listen.c index 42c4040f0c8..45df1f6c36c 100644 --- a/platform-listen.c +++ b/platform-listen.c @@ -34,6 +34,13 @@ platform_pre_listen(void) /* Adjust out-of-memory killer so listening process is not killed */ oom_adjust_setup(); #endif +#ifdef LINUX_MEMLOCK_ONFAULT + /* + * Protect ourselves against kcompactd so that we are able to process + * new connections while it is active and migrating pages. + */ + memlock_onfault_setup(); +#endif } void @@ -82,3 +89,13 @@ platform_post_fork_child(void) #endif } +void platform_pre_session_start(void) +{ +#ifdef LINUX_MEMLOCK_ONFAULT + /* + * Memlock flags are dropped on fork, lock the memory again so that the + * child connection is also protected against kcompactd. + */ + memlock_onfault_setup(); +#endif +} diff --git a/platform.h b/platform.h index 5dec23276a6..08cbd225d6a 100644 --- a/platform.h +++ b/platform.h @@ -24,6 +24,7 @@ void platform_pre_restart(void); void platform_post_listen(void); void platform_post_fork_parent(pid_t child_pid); void platform_post_fork_child(void); +void platform_pre_session_start(void); int platform_privileged_uidswap(void); void platform_setusercontext(struct passwd *); void platform_setusercontext_post_groups(struct passwd *); diff --git a/progressmeter.c b/progressmeter.c index 9d3a9b74d46..04e75a363c9 100644 --- a/progressmeter.c +++ b/progressmeter.c @@ -1,4 +1,4 @@ -/* $OpenBSD: progressmeter.c,v 1.53 2023/04/12 14:22:04 jsg Exp $ */ +/* $OpenBSD: progressmeter.c,v 1.54 2024/09/22 12:56:21 jsg Exp $ */ /* * Copyright (c) 2003 Nils Nordman. All rights reserved. * @@ -46,7 +46,6 @@ #define DEFAULT_WINSIZE 80 #define MAX_WINSIZE 512 -#define PADDING 1 /* padding between the progress indicators */ #define UPDATE_INTERVAL 1 /* update the progress meter every second */ #define STALL_TIME 5 /* we're stalled after this many seconds */ diff --git a/readconf.c b/readconf.c index 39e615b805f..3605a50e4e5 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.387 2024/05/17 02:39:11 jsg Exp $ */ +/* $OpenBSD: readconf.c,v 1.398 2025/03/18 04:53:14 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -71,6 +71,7 @@ #include "uidswap.h" #include "myproposal.h" #include "digest.h" +#include "version.h" /* Format of the configuration file: @@ -134,11 +135,11 @@ */ static int read_config_file_depth(const char *filename, struct passwd *pw, - const char *host, const char *original_host, Options *options, - int flags, int *activep, int *want_final_pass, int depth); + const char *host, const char *original_host, const char *remote_command, + Options *options, int flags, int *activep, int *want_final_pass, int depth); static int process_config_line_depth(Options *options, struct passwd *pw, - const char *host, const char *original_host, char *line, - const char *filename, int linenum, int *activep, int flags, + const char *host, const char *original_host, const char *remote_command, + char *line, const char *filename, int linenum, int *activep, int flags, int *want_final_pass, int depth); /* Keyword tokens. */ @@ -180,6 +181,7 @@ typedef enum { oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump, oSecurityKeyProvider, oKnownHostsCommand, oRequiredRSASize, oEnableEscapeCommandline, oObscureKeystrokeTiming, oChannelTimeout, + oVersionAddendum, oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported } OpCodes; @@ -330,6 +332,7 @@ static struct { { "enableescapecommandline", oEnableEscapeCommandline }, { "obscurekeystroketiming", oObscureKeystrokeTiming }, { "channeltimeout", oChannelTimeout }, + { "versionaddendum", oVersionAddendum }, { NULL, oBadOption } }; @@ -652,25 +655,80 @@ check_match_ifaddrs(const char *addrlist) #endif /* HAVE_IFADDRS_H */ } +/* + * Expand a "match exec" command or an Include path, caller must free returned + * value. + */ +static char * +expand_match_exec_or_include_path(const char *path, Options *options, + struct passwd *pw, const char *host_arg, const char *original_host, + int final_pass, int is_include_path) +{ + char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; + char uidstr[32], *conn_hash_hex, *keyalias, *jmphost, *ruser; + char *host, *ret; + int port; + + port = options->port <= 0 ? default_ssh_port() : options->port; + ruser = options->user == NULL ? pw->pw_name : options->user; + if (final_pass) { + host = xstrdup(options->hostname); + } else if (options->hostname != NULL) { + /* NB. Please keep in sync with ssh.c:main() */ + host = percent_expand(options->hostname, + "h", host_arg, (char *)NULL); + } else { + host = xstrdup(host_arg); + } + if (gethostname(thishost, sizeof(thishost)) == -1) + fatal("gethostname: %s", strerror(errno)); + jmphost = option_clear_or_none(options->jump_host) ? + "" : options->jump_host; + strlcpy(shorthost, thishost, sizeof(shorthost)); + shorthost[strcspn(thishost, ".")] = '\0'; + snprintf(portstr, sizeof(portstr), "%d", port); + snprintf(uidstr, sizeof(uidstr), "%llu", + (unsigned long long)pw->pw_uid); + conn_hash_hex = ssh_connection_hash(thishost, host, + portstr, ruser, jmphost); + keyalias = options->host_key_alias ? options->host_key_alias : host; + + ret = (is_include_path ? percent_dollar_expand : percent_expand)(path, + "C", conn_hash_hex, + "L", shorthost, + "d", pw->pw_dir, + "h", host, + "k", keyalias, + "l", thishost, + "n", original_host, + "p", portstr, + "r", ruser, + "u", pw->pw_name, + "i", uidstr, + "j", jmphost, + (char *)NULL); + free(host); + free(conn_hash_hex); + return ret; +} + /* * Parse and execute a Match directive. */ static int -match_cfg_line(Options *options, char **condition, struct passwd *pw, - const char *host_arg, const char *original_host, int final_pass, - int *want_final_pass, const char *filename, int linenum) +match_cfg_line(Options *options, const char *full_line, int *acp, char ***avp, + struct passwd *pw, const char *host_arg, const char *original_host, + const char *remote_command, int final_pass, int *want_final_pass, + const char *filename, int linenum) { - char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; + char *arg, *oattrib = NULL, *attrib = NULL, *cmd, *host, *criteria; const char *ruser; - int r, port, this_result, result = 1, attributes = 0, negate; - char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; - char uidstr[32]; + int r, this_result, result = 1, attributes = 0, negate; /* * Configuration is likely to be incomplete at this point so we * must be prepared to use default values. */ - port = options->port <= 0 ? default_ssh_port() : options->port; ruser = options->user == NULL ? pw->pw_name : options->user; if (final_pass) { host = xstrdup(options->hostname); @@ -683,11 +741,12 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, } debug2("checking match for '%s' host %s originally %s", - cp, host, original_host); - while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') { + full_line, host, original_host); + while ((attrib = argv_next(acp, avp)) != NULL) { + attrib = oattrib = xstrdup(attrib); /* Terminate on comment */ if (*attrib == '#') { - cp = NULL; /* mark all arguments consumed */ + argv_consume(acp); break; } arg = criteria = NULL; @@ -696,7 +755,8 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, attrib++; /* Criterion "all" has no argument and must appear alone */ if (strcasecmp(attrib, "all") == 0) { - if (attributes > 1 || ((arg = strdelim(&cp)) != NULL && + if (attributes > 1 || + ((arg = argv_next(acp, avp)) != NULL && *arg != '\0' && *arg != '#')) { error("%.200s line %d: '%s' cannot be combined " "with other Match attributes", @@ -705,7 +765,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, goto out; } if (arg != NULL && *arg == '#') - cp = NULL; /* mark all arguments consumed */ + argv_consume(acp); /* consume remaining args */ if (result) result = negate ? 0 : 1; goto out; @@ -729,9 +789,36 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, this_result ? "" : "not ", oattrib); continue; } - /* All other criteria require an argument */ - if ((arg = strdelim(&cp)) == NULL || - *arg == '\0' || *arg == '#') { + + /* Keep this list in sync with below */ + if (strprefix(attrib, "host=", 1) != NULL || + strprefix(attrib, "originalhost=", 1) != NULL || + strprefix(attrib, "user=", 1) != NULL || + strprefix(attrib, "localuser=", 1) != NULL || + strprefix(attrib, "localnetwork=", 1) != NULL || + strprefix(attrib, "version=", 1) != NULL || + strprefix(attrib, "tagged=", 1) != NULL || + strprefix(attrib, "command=", 1) != NULL || + strprefix(attrib, "exec=", 1) != NULL) { + arg = strchr(attrib, '='); + *(arg++) = '\0'; + } else if ((arg = argv_next(acp, avp)) == NULL) { + error("%.200s line %d: missing argument for Match '%s'", + filename, linenum, oattrib); + result = -1; + goto out; + } + + /* + * All other criteria require an argument, though it may + * be the empty string for the "tagged" and "command" + * options. + */ + if (*arg == '\0' && + strcasecmp(attrib, "tagged") != 0 && + strcasecmp(attrib, "command") != 0) + arg = NULL; + if (arg == NULL || *arg == '#') { error("Missing Match criteria for %s", attrib); result = -1; goto out; @@ -765,44 +852,47 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, r = check_match_ifaddrs(arg) == 1; if (r == (negate ? 1 : 0)) this_result = result = 0; + } else if (strcasecmp(attrib, "version") == 0) { + criteria = xstrdup(SSH_RELEASE); + r = match_pattern_list(SSH_RELEASE, arg, 0) == 1; + if (r == (negate ? 1 : 0)) + this_result = result = 0; } else if (strcasecmp(attrib, "tagged") == 0) { criteria = xstrdup(options->tag == NULL ? "" : options->tag); + /* Special case: empty criteria matches empty arg */ + r = (*criteria == '\0') ? *arg == '\0' : + match_pattern_list(criteria, arg, 0) == 1; + if (r == (negate ? 1 : 0)) + this_result = result = 0; + } else if (strcasecmp(attrib, "command") == 0) { + criteria = xstrdup(remote_command == NULL ? + "" : remote_command); + /* Special case: empty criteria matches empty arg */ + r = (*criteria == '\0') ? *arg == '\0' : + match_pattern_list(criteria, arg, 0) == 1; + if (r == (negate ? 1 : 0)) + this_result = result = 0; + } else if (strcasecmp(attrib, "sessiontype") == 0) { + if (options->session_type == SESSION_TYPE_SUBSYSTEM) + criteria = xstrdup("subsystem"); + else if (options->session_type == SESSION_TYPE_NONE) + criteria = xstrdup("none"); + else if (remote_command != NULL && + *remote_command != '\0') + criteria = xstrdup("exec"); + else + criteria = xstrdup("shell"); r = match_pattern_list(criteria, arg, 0) == 1; if (r == (negate ? 1 : 0)) this_result = result = 0; } else if (strcasecmp(attrib, "exec") == 0) { - char *conn_hash_hex, *keyalias, *jmphost; - - if (gethostname(thishost, sizeof(thishost)) == -1) - fatal("gethostname: %s", strerror(errno)); - jmphost = option_clear_or_none(options->jump_host) ? - "" : options->jump_host; - strlcpy(shorthost, thishost, sizeof(shorthost)); - shorthost[strcspn(thishost, ".")] = '\0'; - snprintf(portstr, sizeof(portstr), "%d", port); - snprintf(uidstr, sizeof(uidstr), "%llu", - (unsigned long long)pw->pw_uid); - conn_hash_hex = ssh_connection_hash(thishost, host, - portstr, ruser, jmphost); - keyalias = options->host_key_alias ? - options->host_key_alias : host; - - cmd = percent_expand(arg, - "C", conn_hash_hex, - "L", shorthost, - "d", pw->pw_dir, - "h", host, - "k", keyalias, - "l", thishost, - "n", original_host, - "p", portstr, - "r", ruser, - "u", pw->pw_name, - "i", uidstr, - "j", jmphost, - (char *)NULL); - free(conn_hash_hex); + if ((cmd = expand_match_exec_or_include_path(arg, + options, pw, host_arg, original_host, + final_pass, 0)) == NULL) { + fatal("%.200s line %d: failed to expand match " + "exec '%.100s'", filename, linenum, arg); + } if (result != 1) { /* skip execution if prior predicate failed */ debug3("%.200s line %d: skipped exec " @@ -833,6 +923,8 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, criteria == NULL ? "" : criteria, criteria == NULL ? "" : "\""); free(criteria); + free(oattrib); + oattrib = attrib = NULL; } if (attributes == 0) { error("One or more attributes required for Match"); @@ -842,7 +934,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, out: if (result != -1) debug2("match %sfound", result ? "" : "not "); - *condition = cp; + free(oattrib); free(host); return result; } @@ -1009,7 +1101,7 @@ static const struct multistate multistate_pubkey_auth[] = { }; static const struct multistate multistate_compression[] = { #ifdef WITH_ZLIB - { "yes", COMP_ZLIB }, + { "yes", COMP_DELAYED }, #endif { "no", COMP_NONE }, { NULL, -1 } @@ -1038,18 +1130,19 @@ parse_multistate_value(const char *arg, const char *filename, int linenum, */ int process_config_line(Options *options, struct passwd *pw, const char *host, - const char *original_host, char *line, const char *filename, - int linenum, int *activep, int flags) + const char *original_host, const char *remote_command, char *line, + const char *filename, int linenum, int *activep, int flags) { return process_config_line_depth(options, pw, host, original_host, - line, filename, linenum, activep, flags, NULL, 0); + remote_command, line, filename, linenum, activep, flags, NULL, 0); } #define WHITESPACE " \t\r\n" static int process_config_line_depth(Options *options, struct passwd *pw, const char *host, - const char *original_host, char *line, const char *filename, - int linenum, int *activep, int flags, int *want_final_pass, int depth) + const char *original_host, const char *remote_command, char *line, + const char *filename, int linenum, int *activep, int flags, + int *want_final_pass, int depth) { char *str, **charptr, *endofnumber, *keyword, *arg, *arg2, *p; char **cpptr, ***cppptr, fwdarg[256]; @@ -1785,22 +1878,15 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, "option"); goto out; } - value = match_cfg_line(options, &str, pw, host, original_host, - flags & SSHCONF_FINAL, want_final_pass, - filename, linenum); + value = match_cfg_line(options, str, &ac, &av, pw, host, + original_host, remote_command, flags & SSHCONF_FINAL, + want_final_pass, filename, linenum); if (value < 0) { error("%.200s line %d: Bad Match condition", filename, linenum); goto out; } *activep = (flags & SSHCONF_NEVERMATCH) ? 0 : value; - /* - * If match_cfg_line() didn't consume all its arguments then - * arrange for the extra arguments check below to fail. - */ - - if (str == NULL || *str == '\0') - argv_consume(&ac); break; case oEscapeChar: @@ -1997,6 +2083,15 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, filename, linenum, keyword); goto out; } + /* Expand %tokens and environment variables */ + if ((p = expand_match_exec_or_include_path(arg, + options, pw, host, original_host, + flags & SSHCONF_FINAL, 1)) == NULL) { + error("%.200s line %d: Unable to expand user " + "config file '%.100s'", + filename, linenum, arg); + continue; + } /* * Ensure all paths are anchored. User configuration * files may begin with '~/' but system configurations @@ -2004,17 +2099,19 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, * as living in ~/.ssh for user configurations or * /etc/ssh for system ones. */ - if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0) { + if (*p == '~' && (flags & SSHCONF_USERCONF) == 0) { error("%.200s line %d: bad include path %s.", - filename, linenum, arg); + filename, linenum, p); goto out; } - if (!path_absolute(arg) && *arg != '~') { + if (!path_absolute(p) && *p != '~') { xasprintf(&arg2, "%s/%s", (flags & SSHCONF_USERCONF) ? - "~/" _PATH_SSH_USER_DIR : SSHDIR, arg); - } else - arg2 = xstrdup(arg); + "~/" _PATH_SSH_USER_DIR : SSHDIR, p); + } else { + arg2 = xstrdup(p); + } + free(p); memset(&gl, 0, sizeof(gl)); #ifdef WINDOWS convertToForwardslash(arg2); @@ -2039,13 +2136,14 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, gl.gl_pathv[i], depth, oactive ? "" : " (parse only)"); r = read_config_file_depth(gl.gl_pathv[i], - pw, host, original_host, options, - flags | SSHCONF_CHECKPERM | + pw, host, original_host, remote_command, + options, flags | SSHCONF_CHECKPERM | (oactive ? 0 : SSHCONF_NEVERMATCH), activep, want_final_pass, depth + 1); if (r != 1 && errno != ENOENT) { - error("Can't open user config file " - "%.100s: %.100s", gl.gl_pathv[i], + error("%.200s line %d: Can't open user " + "config file %.100s: %.100s", + filename, linenum, gl.gl_pathv[i], strerror(errno)); globfree(&gl); goto out; @@ -2399,6 +2497,28 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, } break; + case oVersionAddendum: + if (str == NULL || *str == '\0') + fatal("%s line %d: %s missing argument.", + filename, linenum, keyword); + len = strspn(str, WHITESPACE); + if (strchr(str + len, '\r') != NULL) { + fatal("%.200s line %d: Invalid %s argument", + filename, linenum, keyword); + } + if ((arg = strchr(line, '#')) != NULL) { + *arg = '\0'; + rtrim(line); + } + if (*activep && options->version_addendum == NULL) { + if (strcasecmp(str + len, "none") == 0) + options->version_addendum = xstrdup(""); + else + options->version_addendum = xstrdup(str + len); + } + argv_consume(&ac); + break; + case oDeprecated: debug("%s line %d: Deprecated option \"%s\"", filename, linenum, keyword); @@ -2440,20 +2560,20 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, */ int read_config_file(const char *filename, struct passwd *pw, const char *host, - const char *original_host, Options *options, int flags, + const char *original_host, const char *remote_command, Options *options, int flags, int *want_final_pass) { int active = 1; return read_config_file_depth(filename, pw, host, original_host, - options, flags, &active, want_final_pass, 0); + remote_command, options, flags, &active, want_final_pass, 0); } #define READCONF_MAX_DEPTH 16 static int read_config_file_depth(const char *filename, struct passwd *pw, - const char *host, const char *original_host, Options *options, - int flags, int *activep, int *want_final_pass, int depth) + const char *host, const char *original_host, const char *remote_command, + Options *options, int flags, int *activep, int *want_final_pass, int depth) { FILE *f; char *line = NULL; @@ -2504,8 +2624,8 @@ read_config_file_depth(const char *filename, struct passwd *pw, * line numbers later for error messages. */ if (process_config_line_depth(options, pw, host, original_host, - line, filename, linenum, activep, flags, want_final_pass, - depth) != 0) + remote_command, line, filename, linenum, activep, flags, + want_final_pass, depth) != 0) bad_options++; } free(line); @@ -2666,6 +2786,7 @@ initialize_options(Options * options) options->tag = NULL; options->channel_timeouts = NULL; options->num_channel_timeouts = 0; + options->version_addendum = NULL; } /* @@ -3384,6 +3505,8 @@ fmt_intarg(OpCodes code, int val) switch (code) { case oAddressFamily: return fmt_multistate_int(val, multistate_addressfamily); + case oCompression: + return fmt_multistate_int(val, multistate_compression); case oVerifyHostKeyDNS: case oUpdateHostkeys: return fmt_multistate_int(val, multistate_yesnoask); @@ -3621,6 +3744,7 @@ dump_client_config(Options *o, const char *host) dump_cfg_string(oXAuthLocation, o->xauth_location); dump_cfg_string(oKnownHostsCommand, o->known_hosts_command); dump_cfg_string(oTag, o->tag); + dump_cfg_string(oVersionAddendum, o->version_addendum); /* Forwards */ dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards); diff --git a/readconf.h b/readconf.h index 9447d5d6e53..cd49139b13c 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.156 2024/03/04 02:16:11 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.159 2025/02/15 01:48:30 djm Exp $ */ /* * Author: Tatu Ylonen @@ -19,7 +19,6 @@ /* Data structure for representing option data. */ #define SSH_MAX_HOSTS_FILES 32 -#define MAX_CANON_DOMAINS 32 #define PATH_MAX_SUN (sizeof((struct sockaddr_un *)0)->sun_path) struct allowed_cname { @@ -185,6 +184,8 @@ typedef struct { char **channel_timeouts; /* inactivity timeout by channel type */ u_int num_channel_timeouts; + char *version_addendum; + char *ignored_unknown; /* Pattern list of unknown tokens to ignore */ } Options; @@ -239,9 +240,9 @@ int fill_default_options(Options *); void fill_default_options_for_canonicalization(Options *); void free_options(Options *o); int process_config_line(Options *, struct passwd *, const char *, - const char *, char *, const char *, int, int *, int); + const char *, const char *, char *, const char *, int, int *, int); int read_config_file(const char *, struct passwd *, const char *, - const char *, Options *, int, int *); + const char *, const char *, Options *, int, int *); int parse_forward(struct Forward *, const char *, int, int); int parse_jump(const char *, Options *, int); int parse_ssh_uri(const char *, char **, char **, int *); diff --git a/regress/Makefile b/regress/Makefile index 7f7349706be..7e7f95b58a2 100644 --- a/regress/Makefile +++ b/regress/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.135 2024/06/14 04:43:11 djm Exp $ +# $OpenBSD: Makefile,v 1.136 2025/03/11 07:50:20 dtucker Exp $ tests: prep file-tests t-exec unit @@ -65,6 +65,7 @@ LTESTS= connect \ sftp-batch \ sftp-glob \ sftp-perm \ + sftp-resume \ sftp-uri \ reconfigure \ dynamic-forward \ diff --git a/regress/agent-restrict.sh b/regress/agent-restrict.sh index ea932db10e1..cd10a618d28 100644 --- a/regress/agent-restrict.sh +++ b/regress/agent-restrict.sh @@ -1,4 +1,4 @@ -# $OpenBSD: agent-restrict.sh,v 1.6 2023/03/01 09:29:32 dtucker Exp $ +# $OpenBSD: agent-restrict.sh,v 1.7 2025/03/28 21:45:55 dtucker Exp $ # Placed in the Public Domain. tid="agent restrictions" @@ -45,14 +45,14 @@ Host host_$h Hostname host_$h HostkeyAlias host_$h IdentityFile $OBJ/user_$h - ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h + ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${TEST_SSH_SSHD_ENV} ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h _EOF # Variant with no specified keys. cat << _EOF >> $OBJ/ssh_proxy_noid Host host_$h Hostname host_$h HostkeyAlias host_$h - ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h + ProxyCommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${TEST_SSH_SSHD_ENV} ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy_host_$h _EOF done cat $OBJ/ssh_proxy.bak >> $OBJ/ssh_proxy diff --git a/regress/agent.sh b/regress/agent.sh index 5d41fae1ceb..2c98b700d77 100644 --- a/regress/agent.sh +++ b/regress/agent.sh @@ -1,4 +1,4 @@ -# $OpenBSD: agent.sh,v 1.21 2023/03/01 09:29:32 dtucker Exp $ +# $OpenBSD: agent.sh,v 1.22 2024/10/24 03:28:34 djm Exp $ # Placed in the Public Domain. tid="simple agent test" @@ -163,7 +163,7 @@ done ## Deletion tests. -trace "delete all agent keys" +trace "delete all agent keys using -D" ${SSHADD} -D > /dev/null 2>&1 r=$? if [ $r -ne 0 ]; then @@ -187,6 +187,29 @@ r=$? if [ $r -ne 0 ]; then fail "ssh-add -l failed: exit code $r" fi +trace "delete all agent keys using SIGUSR1" +kill -s USR1 $SSH_AGENT_PID +r=$? +if [ $r -ne 0 ]; then + fail "kill -s USR1 failed: exit code $r" +fi +# make sure they're gone +${SSHADD} -l > /dev/null 2>&1 +r=$? +if [ $r -ne 1 ]; then + fail "ssh-add -l returned unexpected exit code: $r" +fi +# re-add keys/certs to agent +for t in ${SSH_KEYTYPES}; do + ${SSHADD} $OBJ/$t-agent-private >/dev/null 2>&1 || \ + fail "ssh-add failed exit code $?" +done +# make sure they are there +${SSHADD} -l > /dev/null 2>&1 +r=$? +if [ $r -ne 0 ]; then + fail "ssh-add -l failed: exit code $r" +fi check_key_absent() { ${SSHADD} -L | grep "^$1 " >/dev/null diff --git a/regress/cert-userkey.sh b/regress/cert-userkey.sh index d3bc1d6e6bd..4dac8c307ba 100644 --- a/regress/cert-userkey.sh +++ b/regress/cert-userkey.sh @@ -1,10 +1,10 @@ -# $OpenBSD: cert-userkey.sh,v 1.28 2021/09/30 05:26:26 dtucker Exp $ +# $OpenBSD: cert-userkey.sh,v 1.29 2024/12/06 16:25:58 djm Exp $ # Placed in the Public Domain. tid="certified user keys" -rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* -cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak +rm -f $OBJ/authorized_keys_${USER}* $OBJ/user_ca_key* $OBJ/cert_user_key* +rm -f $OBJ/authorized_principals* cp $OBJ/ssh_proxy $OBJ/ssh_proxy_bak if [ "$os" == "windows" ]; then # remove CR (carriage return) @@ -13,6 +13,10 @@ else PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` fi +grep -v AuthorizedKeysFile $OBJ/sshd_proxy > $OBJ/sshd_proxy_bak +echo "AuthorizedKeysFile $OBJ/authorized_keys_%u_*" >> $OBJ/sshd_proxy_bak + +PLAIN_TYPES=`$SSH -Q key-plain | maybe_filter_sk | sed 's/^ssh-dss/ssh-dsa/;s/^ssh-//'` EXTRA_TYPES="" rsa="" @@ -68,11 +72,15 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do _prefix="${ktype}" # Setup for AuthorizedPrincipalsFile - rm -f $OBJ/authorized_keys_$USER + rm -f $OBJ/authorized_keys_${USER}* $OBJ/authorized_principals_${USER}* + touch $OBJ/authorized_keys_${USER}_A + touch $OBJ/authorized_keys_${USER}_Z + touch $OBJ/authorized_principals_${USER}_A + touch $OBJ/authorized_principals_${USER}_Z ( cat $OBJ/sshd_proxy_bak echo "AuthorizedPrincipalsFile " \ - "$OBJ/authorized_principals_%u" + "$OBJ/authorized_principals_%u_*" echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" echo "PubkeyAcceptedAlgorithms ${t}" ) > $OBJ/sshd_proxy @@ -83,7 +91,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # Missing authorized_principals verbose "$tid: ${_prefix} missing authorized_principals" - rm -f $OBJ/authorized_principals_$USER + rm -f $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -92,7 +100,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # Empty authorized_principals verbose "$tid: ${_prefix} empty authorized_principals" - echo > $OBJ/authorized_principals_$USER + echo > $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -101,7 +109,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # Wrong authorized_principals verbose "$tid: ${_prefix} wrong authorized_principals" - echo gregorsamsa > $OBJ/authorized_principals_$USER + echo gregorsamsa > $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -110,7 +118,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # Correct authorized_principals verbose "$tid: ${_prefix} correct authorized_principals" - echo mekmitasdigoat > $OBJ/authorized_principals_$USER + echo mekmitasdigoat > $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -ne 0 ]; then @@ -119,7 +127,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # authorized_principals with bad key option verbose "$tid: ${_prefix} authorized_principals bad key opt" - echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_$USER + echo 'blah mekmitasdigoat' > $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -129,7 +137,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # authorized_principals with command=false verbose "$tid: ${_prefix} authorized_principals command=false" echo 'command="false" mekmitasdigoat' > \ - $OBJ/authorized_principals_$USER + $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -140,7 +148,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do # authorized_principals with command=true verbose "$tid: ${_prefix} authorized_principals command=true" echo 'command="true" mekmitasdigoat' > \ - $OBJ/authorized_principals_$USER + $OBJ/authorized_principals_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost false >/dev/null 2>&1 if [ $? -ne 0 ]; then @@ -148,7 +156,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do fi # Setup for principals= key option - rm -f $OBJ/authorized_principals_$USER + rm -f $OBJ/authorized_principals_${USER}_X ( cat $OBJ/sshd_proxy_bak echo "PubkeyAcceptedAlgorithms ${t}" @@ -163,7 +171,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do ( printf 'cert-authority,principals="gregorsamsa" ' cat $OBJ/user_ca_key.pub - ) > $OBJ/authorized_keys_$USER + ) > $OBJ/authorized_keys_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -eq 0 ]; then @@ -175,7 +183,7 @@ for ktype in $EXTRA_TYPES $PLAIN_TYPES ; do ( printf 'cert-authority,principals="mekmitasdigoat" ' cat $OBJ/user_ca_key.pub - ) > $OBJ/authorized_keys_$USER + ) > $OBJ/authorized_keys_${USER}_X ${SSH} -i $OBJ/cert_user_key_${ktype} \ -F $OBJ/ssh_proxy somehost true >/dev/null 2>&1 if [ $? -ne 0 ]; then @@ -185,14 +193,17 @@ done basic_tests() { auth=$1 + rm -f $OBJ/authorized_keys_${USER}* + touch $OBJ/authorized_keys_${USER}_A + touch $OBJ/authorized_keys_${USER}_Z if test "x$auth" = "xauthorized_keys" ; then # Add CA to authorized_keys ( printf 'cert-authority ' cat $OBJ/user_ca_key.pub - ) > $OBJ/authorized_keys_$USER + ) > $OBJ/authorized_keys_${USER}_X else - echo > $OBJ/authorized_keys_$USER + echo > $OBJ/authorized_keys_${USER}_X extra_sshd="TrustedUserCAKeys $OBJ/user_ca_key.pub" fi @@ -300,9 +311,9 @@ test_one() { ( printf "cert-authority${auth_opt} " cat $OBJ/user_ca_key.pub - ) > $OBJ/authorized_keys_$USER + ) > $OBJ/authorized_keys_${USER}_X else - echo > $OBJ/authorized_keys_$USER + echo > $OBJ/authorized_keys_${USER}_X echo "TrustedUserCAKeys $OBJ/user_ca_key.pub" \ >> $OBJ/sshd_proxy echo "PubkeyAcceptedAlgorithms ${t}*" \ @@ -351,15 +362,15 @@ test_one "empty principals" failure "" TrustedUserCAKeys # should always be refused. # AuthorizedPrincipalsFile -rm -f $OBJ/authorized_keys_$USER -echo mekmitasdigoat > $OBJ/authorized_principals_$USER +rm -f $OBJ/authorized_keys_${USER}_X +echo mekmitasdigoat > $OBJ/authorized_principals_${USER}_X test_one "AuthorizedPrincipalsFile principals" success "-n mekmitasdigoat" \ - TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" + TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u_*" test_one "AuthorizedPrincipalsFile no principals" failure "" \ - TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u" + TrustedUserCAKeys "AuthorizedPrincipalsFile $OBJ/authorized_principals_%u_*" # principals= key option -rm -f $OBJ/authorized_principals_$USER +rm -f $OBJ/authorized_principals_${USER}_X test_one "principals key option principals" success "-n mekmitasdigoat" \ authorized_keys ',principals="mekmitasdigoat"' test_one "principals key option no principals" failure "" \ @@ -396,6 +407,6 @@ for ktype in $PLAIN_TYPES ; do fi done -rm -f $OBJ/authorized_keys_$USER $OBJ/user_ca_key* $OBJ/cert_user_key* -rm -f $OBJ/authorized_principals_$USER +rm -f $OBJ/authorized_keys_${USER}* $OBJ/user_ca_key* $OBJ/cert_user_key* +rm -f $OBJ/authorized_principals* diff --git a/regress/cfginclude.sh b/regress/cfginclude.sh index 9f496f0ea61..73903485218 100644 --- a/regress/cfginclude.sh +++ b/regress/cfginclude.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cfginclude.sh,v 1.3 2021/06/08 06:52:43 djm Exp $ +# $OpenBSD: cfginclude.sh,v 1.5 2024/09/27 01:05:54 djm Exp $ # Placed in the Public Domain. tid="config include" @@ -10,7 +10,7 @@ cat > $OBJ/ssh_config.i << _EOF Match host a Hostname aa -Match host b # comment +Match host=b # comment Hostname bb Include $OBJ/ssh_config.i.* @@ -18,7 +18,7 @@ Match host c Include $OBJ/ssh_config.i.* Hostname cc -Match host m +Match host=m !user xxxyfake Include $OBJ/ssh_config.i.* # comment Host d @@ -41,7 +41,7 @@ Match host xxxxxx _EOF cat > $OBJ/ssh_config.i.1 << _EOF -Match host a +Match host=a Hostname aaa Match host b @@ -64,10 +64,10 @@ cat > $OBJ/ssh_config.i.2 << _EOF Match host a Hostname aaaa -Match host b +Match host=b !user blahblahfake Hostname bbbb -Match host c +Match host=c Hostname cccc Host d @@ -150,7 +150,7 @@ trial a aa # cleanup rm -f $OBJ/ssh_config.i $OBJ/ssh_config.i.* $OBJ/ssh_config.out -# $OpenBSD: cfginclude.sh,v 1.3 2021/06/08 06:52:43 djm Exp $ +# $OpenBSD: cfginclude.sh,v 1.5 2024/09/27 01:05:54 djm Exp $ # Placed in the Public Domain. tid="config include" @@ -306,5 +306,27 @@ _EOF ${REAL_SSH} -F $OBJ/ssh_config.i -G a 2>/dev/null && \ fail "ssh include allowed infinite recursion?" # or hang... +# Environment variable expansion +cat > $OBJ/ssh_config.i << _EOF +Include $OBJ/ssh_config.\${REAL_FILE} +_EOF +cat > $OBJ/ssh_config.i.x << _EOF +Hostname xyzzy +_EOF +REAL_FILE=i.x +export REAL_FILE +trial a xyzzy + +# Environment variable expansion +cat > $OBJ/ssh_config.i << _EOF +Include $OBJ/ssh_config.i.%h%h +_EOF +cat > $OBJ/ssh_config.i.blahblah << _EOF +Hostname mekmitastdigoat +_EOF +REAL_FILE=i.x +export REAL_FILE +trial blah mekmitastdigoat + # cleanup rm -f $OBJ/ssh_config.i $OBJ/ssh_config.i.* $OBJ/ssh_config.out diff --git a/regress/cfgmatch.sh b/regress/cfgmatch.sh index d6931bb1b69..0c5d27c23c8 100644 --- a/regress/cfgmatch.sh +++ b/regress/cfgmatch.sh @@ -1,4 +1,4 @@ -# $OpenBSD: cfgmatch.sh,v 1.13 2021/06/08 06:52:43 djm Exp $ +# $OpenBSD: cfgmatch.sh,v 1.14 2024/09/27 01:05:54 djm Exp $ # Placed in the Public Domain. tid="sshd_config match" @@ -141,43 +141,45 @@ stop_client # requires knowledge of actual group memberships user running the test). params="user:user:u1 host:host:h1 address:addr:1.2.3.4 \ localaddress:laddr:5.6.7.8 rdomain:rdomain:rdom1" -cp $OBJ/sshd_proxy_bak $OBJ/sshd_config -echo 'Banner /nomatch' >>$OBJ/sshd_config -for i in $params; do - config=`echo $i | cut -f1 -d:` - criteria=`echo $i | cut -f2 -d:` - value=`echo $i | cut -f3 -d:` - cat >>$OBJ/sshd_config </dev/null || \ + fail "validate config for w/out spec" + + # Test matching each criteria. + for i in $params; do + testcriteria=`echo $i | cut -f2 -d:` + expected=/`echo $i | cut -f3 -d:` + spec="" + for j in $params; do + config=`echo $j | cut -f1 -d:` + criteria=`echo $j | cut -f2 -d:` + value=`echo $j | cut -f3 -d:` + if [ "$criteria" = "$testcriteria" ]; then + spec="$criteria=$value,$spec" + else + spec="$criteria=1$value,$spec" + fi + done + trace "test spec $spec" + result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \ + awk '$1=="banner"{print $2}'` + if [ "$os" == "windows" ]; then + result=${result/$'\r'/} # remove CR (carriage return) + fi + if [ "$result" != "$expected" ]; then + fail "match $config expected $expected got $result" fi done - trace "test spec $spec" - result=`${SUDO} ${SSHD} -f $OBJ/sshd_config -T -C "$spec" | \ - awk '$1=="banner"{print $2}'` - if [ "$os" == "windows" ]; then - result=${result/$'\r'/} # remove CR (carriage return) - fi - if [ "$result" != "$expected" ]; then - fail "match $config expected $expected got $result" - fi done diff --git a/regress/dropbear-ciphers.sh b/regress/dropbear-ciphers.sh index 1500fa0e725..c58cb90c76c 100644 --- a/regress/dropbear-ciphers.sh +++ b/regress/dropbear-ciphers.sh @@ -1,4 +1,4 @@ -# $OpenBSD: dropbear-ciphers.sh,v 1.3 2024/06/20 08:23:18 dtucker Exp $ +# $OpenBSD: dropbear-ciphers.sh,v 1.4 2025/03/11 07:43:03 dtucker Exp $ # Placed in the Public Domain. tid="dropbear ciphers" @@ -26,7 +26,7 @@ for c in $ciphers ; do for kt in $keytype; do verbose "$tid: cipher $c mac $m kt $kt" rm -f ${COPY} - env HOME=$OBJ dbclient -y -i $OBJ/.dropbear/$kt 2>$OBJ/dbclient.log \ + env HOME=$OBJ ${DBCLIENT} -y -i $OBJ/.dropbear/$kt 2>$OBJ/dbclient.log \ -c $c -m $m -J "$OBJ/ssh_proxy.sh" somehost cat ${DATA} > ${COPY} if [ $? -ne 0 ]; then fail "ssh cat $DATA failed" diff --git a/regress/dropbear-kex.sh b/regress/dropbear-kex.sh index d9f1b32c09d..72717fbb786 100644 --- a/regress/dropbear-kex.sh +++ b/regress/dropbear-kex.sh @@ -1,4 +1,4 @@ -# $OpenBSD: dropbear-kex.sh,v 1.3 2024/06/19 10:10:46 dtucker Exp $ +# $OpenBSD: dropbear-kex.sh,v 1.4 2025/03/11 07:42:08 dtucker Exp $ # Placed in the Public Domain. tid="dropbear kex" @@ -10,8 +10,14 @@ fi cp $OBJ/sshd_proxy $OBJ/sshd_proxy.bak kex="curve25519-sha256 curve25519-sha256@libssh.org" -if $SSH -Q kex | grep 'diffie-hellman-group14-sha1'; then - kex="$kex diffie-hellman-group14-sha256 diffie-hellman-group14-sha1" +if $SSH -Q kex | grep 'diffie-hellman-group14-sha256' >/dev/null; then + kex="$kex diffie-hellman-group14-sha256" +fi +# There's no flag to query KEX, so if MACs does not contain SHA1, assume +# there's also SHA1-based KEX methods either. +if $SSH -Q kex | grep 'diffie-hellman-group14-sha1' >/dev/null && \ + $DBCLIENT -m help hst 2>&1 | grep -- '-sha1' >/dev/null ; then + kex="$kex diffie-hellman-group14-sha1" fi for k in $kex; do @@ -19,8 +25,9 @@ for k in $kex; do rm -f ${COPY} # dbclient doesn't have switch for kex, so force in server (cat $OBJ/sshd_proxy.bak; echo "KexAlgorithms $k") >$OBJ/sshd_proxy - env HOME=$OBJ dbclient -y -i $OBJ/.dropbear/id_ed25519 2>$OBJ/dbclient.log \ - -J "$OBJ/ssh_proxy.sh" somehost cat ${DATA} > ${COPY} + env HOME=$OBJ \ + ${DBCLIENT} -y -i $OBJ/.dropbear/id_ed25519 2>$OBJ/dbclient.log \ + -J "$OBJ/ssh_proxy.sh" somehost cat ${DATA} > ${COPY} if [ $? -ne 0 ]; then fail "ssh cat $DATA failed" fi diff --git a/regress/hostkey-agent.sh b/regress/hostkey-agent.sh index ad674d99001..b6aa24edb78 100644 --- a/regress/hostkey-agent.sh +++ b/regress/hostkey-agent.sh @@ -1,4 +1,4 @@ -# $OpenBSD: hostkey-agent.sh,v 1.13 2021/09/30 05:20:08 dtucker Exp $ +# $OpenBSD: hostkey-agent.sh,v 1.15 2024/12/04 10:51:13 dtucker Exp $ # Placed in the Public Domain. tid="hostkey agent" @@ -93,6 +93,30 @@ for k in $SSH_CERTTYPES ; do fi done +verbose "multiple hostkeys" +cp $OBJ/sshd_proxy.orig $OBJ/sshd_proxy +cp $OBJ/ssh_proxy $OBJ/ssh_proxy.orig +grep -vi 'globalknownhostsfile' $OBJ/ssh_proxy.orig > $OBJ/ssh_proxy +echo "UpdateHostkeys=yes" >> $OBJ/ssh_proxy +echo "GlobalKnownHostsFile=none" >> $OBJ/ssh_proxy + +for k in $SSH_KEYTYPES ; do + verbose "Addkey type $k" + echo "Hostkey $OBJ/agent-key.${k}" >> $OBJ/sshd_proxy + + ( printf 'localhost-with-alias ' ; + cat $OBJ/agent-key.$k.pub) > $OBJ/known_hosts +done + +opts="-oStrictHostKeyChecking=yes -F $OBJ/ssh_proxy" +SSH_CONNECTION=`${SSH} $opts host 'echo $SSH_CONNECTION'` +if [ $? -ne 0 ]; then + fail "connection to server with multiple hostkeys failed" +fi +if [ "$SSH_CONNECTION" != "UNKNOWN 65535 UNKNOWN 65535" ]; then + fail "bad SSH_CONNECTION key while using multiple hostkeys" +fi + trace "kill agent" if [ "$os" == "windows" ]; then #keys added through ssh-add are stored in windows registry so delete them. diff --git a/regress/key-options.sh b/regress/key-options.sh index 623128ca4e6..7f9b45fc0f6 100644 --- a/regress/key-options.sh +++ b/regress/key-options.sh @@ -1,4 +1,4 @@ -# $OpenBSD: key-options.sh,v 1.10 2024/03/25 02:07:08 dtucker Exp $ +# $OpenBSD: key-options.sh,v 1.11 2024/12/05 14:28:39 dtucker Exp $ # Placed in the Public Domain. tid="key options" @@ -120,5 +120,8 @@ check_valid_before() { check_valid_before "default" "" "pass" check_valid_before "invalid" 'expiry-time="INVALID"' "fail" check_valid_before "expired" 'expiry-time="19990101"' "fail" +if config_defined "SIZEOF_TIME_T 4"; then check_valid_before "valid" 'expiry-time="20380101"' "pass" - +else +check_valid_before "valid-64b" 'expiry-time="25250101"' "pass" +fi diff --git a/regress/misc/fuzz-harness/Makefile b/regress/misc/fuzz-harness/Makefile index 107213029e0..55dcc17175c 100644 --- a/regress/misc/fuzz-harness/Makefile +++ b/regress/misc/fuzz-harness/Makefile @@ -4,52 +4,68 @@ CXX=clang++-16 FUZZ_FLAGS=-fsanitize=address,fuzzer -fno-omit-frame-pointer FUZZ_LIBS=-L/usr/lib/llvm-16/lib -lFuzzer -CXXFLAGS=-O2 -g -Wall -Wextra -Wno-unused-parameter -Wno-exceptions -I ../../.. $(FUZZ_FLAGS) -CFLAGS=$(CXXFLAGS) -LDFLAGS=-L ../../.. -L ../../../openbsd-compat -g $(FUZZ_FLAGS) +CFLAGS=-D_GNU_SOURCE=1 -O2 -g -Wall -Wextra -Wno-unused-parameter -Wno-exceptions -Wno-deprecated -I ../../.. +CXXFLAGS=$(CFLAGS) $(FUZZ_FLAGS) +LDFLAGS=-L ../../.. -L ../../../openbsd-compat -g LIBS=-lssh -lopenbsd-compat -lmd -lcrypto -lfido2 -lcbor $(FUZZ_LIBS) SK_NULL_OBJS=ssh-sk-null.o COMMON_DEPS=../../../libssh.a TARGETS=pubkey_fuzz sig_fuzz authopt_fuzz authkeys_fuzz sshsig_fuzz \ - sshsigopt_fuzz privkey_fuzz kex_fuzz agent_fuzz + sshsigopt_fuzz privkey_fuzz kex_fuzz agent_fuzz \ + mkcorpus_sntrup761 sntrup761_enc_fuzz sntrup761_dec_fuzz all: $(TARGETS) .cc.o: $(CXX) $(CXXFLAGS) -c $< -o $@ +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + pubkey_fuzz: pubkey_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS) - $(CXX) -o $@ pubkey_fuzz.o $(SK_NULL_OBJS) $(LDFLAGS) $(LIBS) + $(CXX) -o $@ pubkey_fuzz.o $(SK_NULL_OBJS) $(LDFLAGS) $(FUZZ_FLAGS) $(LIBS) sig_fuzz: sig_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS) - $(CXX) -o $@ sig_fuzz.o $(SK_NULL_OBJS) $(LDFLAGS) $(LIBS) + $(CXX) -o $@ sig_fuzz.o $(SK_NULL_OBJS) $(LDFLAGS) $(FUZZ_FLAGS) $(LIBS) authopt_fuzz: authopt_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS) - $(CXX) -o $@ authopt_fuzz.o $(SK_NULL_OBJS) ../../../auth-options.o $(LDFLAGS) $(LIBS) + $(CXX) -o $@ authopt_fuzz.o $(SK_NULL_OBJS) ../../../auth-options.o $(LDFLAGS) $(FUZZ_FLAGS) $(LIBS) authkeys_fuzz: authkeys_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS) - $(CXX) -o $@ authkeys_fuzz.o $(SK_NULL_OBJS) ../../../auth-options.o ../../../auth2-pubkeyfile.o $(LDFLAGS) $(LIBS) + $(CXX) -o $@ authkeys_fuzz.o $(SK_NULL_OBJS) ../../../auth-options.o ../../../auth2-pubkeyfile.o $(LDFLAGS) $(FUZZ_FLAGS) $(LIBS) sshsig_fuzz: sshsig_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS) - $(CXX) -o $@ sshsig_fuzz.o $(SK_NULL_OBJS) ../../../sshsig.o $(LDFLAGS) $(LIBS) + $(CXX) -o $@ sshsig_fuzz.o $(SK_NULL_OBJS) ../../../sshsig.o $(LDFLAGS) $(FUZZ_FLAGS) $(LIBS) sshsigopt_fuzz: sshsigopt_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS) - $(CXX) -o $@ sshsigopt_fuzz.o $(SK_NULL_OBJS) ../../../sshsig.o $(LDFLAGS) $(LIBS) + $(CXX) -o $@ sshsigopt_fuzz.o $(SK_NULL_OBJS) ../../../sshsig.o $(LDFLAGS) $(FUZZ_FLAGS) $(LIBS) privkey_fuzz: privkey_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS) - $(CXX) -o $@ privkey_fuzz.o $(SK_NULL_OBJS) $(LDFLAGS) $(LIBS) + $(CXX) -o $@ privkey_fuzz.o $(SK_NULL_OBJS) $(LDFLAGS) $(FUZZ_FLAGS) $(LIBS) kex_fuzz: kex_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS) - $(CXX) -o $@ kex_fuzz.o $(SK_NULL_OBJS) $(LDFLAGS) $(LIBS) -lz + $(CXX) -o $@ kex_fuzz.o $(SK_NULL_OBJS) $(LDFLAGS) $(FUZZ_FLAGS) $(LIBS) -lz agent_fuzz: agent_fuzz.o agent_fuzz_helper.o sk-dummy.o ../../../ssh-sk.o $(COMMON_DEPS) - $(CXX) -o $@ agent_fuzz.o agent_fuzz_helper.o sk-dummy.o ../../../ssh-sk.o $(LDFLAGS) $(LIBS) -lz + $(CXX) -o $@ agent_fuzz.o agent_fuzz_helper.o sk-dummy.o ../../../ssh-sk.o $(LDFLAGS) $(FUZZ_FLAGS) $(LIBS) -lz agent_fuzz_helper.o: agent_fuzz_helper.c ../../../ssh-agent.c sk-dummy.o: ../sk-dummy/sk-dummy.c - $(CC) $(CFLAGS) -c -o $@ ../sk-dummy/sk-dummy.c -DSK_DUMMY_INTEGRATE=1 $(LDFLAGS) + $(CC) $(CFLAGS) -c -o $@ ../sk-dummy/sk-dummy.c -DSK_DUMMY_INTEGRATE=1 $(LDFLAGS) $(FUZZ_FLAGS) + +mkcorpus_sntrup761: mkcorpus_sntrup761.o + $(CC) -o $@ mkcorpus_sntrup761.o $(LDFLAGS) -lcrypto + +sntrup761_dec_fuzz: sntrup761_dec_fuzz.o + $(CXX) -o $@ sntrup761_dec_fuzz.o $(LDFLAGS) $(FUZZ_FLAGS) $(FUZZ_LIBS) -lcrypto + +sntrup761_enc_fuzz: sntrup761_enc_fuzz.o + $(CXX) -o $@ sntrup761_enc_fuzz.o $(LDFLAGS) $(FUZZ_FLAGS) $(FUZZ_LIBS) -lcrypto clean: -rm -f *.o $(TARGETS) + +cleandir: clean + diff --git a/regress/misc/fuzz-harness/agent_fuzz_helper.c b/regress/misc/fuzz-harness/agent_fuzz_helper.c index 321343bbbbd..2750221154e 100644 --- a/regress/misc/fuzz-harness/agent_fuzz_helper.c +++ b/regress/misc/fuzz-harness/agent_fuzz_helper.c @@ -158,6 +158,7 @@ test_one(const uint8_t* s, size_t slen) SYSLOG_FACILITY_AUTH, 1); devnull = devnull_or_die(); allowed_providers = xstrdup(""); + websafe_allowlist = xstrdup("*"); setenv("DISPLAY", "", 1); /* ban askpass */ } diff --git a/regress/misc/fuzz-harness/mkcorpus_sntrup761.c b/regress/misc/fuzz-harness/mkcorpus_sntrup761.c new file mode 100644 index 00000000000..86a8e02aa99 --- /dev/null +++ b/regress/misc/fuzz-harness/mkcorpus_sntrup761.c @@ -0,0 +1,82 @@ +// Makes basic seed corpora for other fuzzers +// +// Will write to ./sntrup761_pubkey_corpus (for sntrup761_enc_fuzz) and +// to ./sntrup761_ciphertext_corpus (for sntrup761_dec_fuzz) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "crypto_api.h" +#include "hash.c" + +#undef randombytes +#define USE_SNTRUP761X25519 1 +void randombytes(unsigned char *ptr, size_t l); +volatile crypto_int16 crypto_int16_optblocker = 0; +volatile crypto_int32 crypto_int32_optblocker = 0; +volatile crypto_int64 crypto_int64_optblocker = 0; +#include "sntrup761.c" + +#define NSEEDS 1000 + +static int real_random; + +void +randombytes(unsigned char *ptr, size_t l) +{ + if (real_random) + arc4random_buf(ptr, l); + else + memset(ptr, 0, l); +} + +void write_blob(const char *path, int n, const char *suffix, + const void *ptr, size_t l) +{ + char name[256]; + FILE *f; + + snprintf(name, sizeof(name), "%s/%06d.%s", path, n, suffix); + if ((f = fopen(name, "wb+")) == NULL) + err(1, "fopen %s", name); + if (fwrite(ptr, l, 1, f) != 1) + err(1, "write %s", name); + fclose(f); +} + +int main(void) +{ + int i; + unsigned char pk[crypto_kem_sntrup761_PUBLICKEYBYTES]; + unsigned char sk[crypto_kem_sntrup761_SECRETKEYBYTES]; + unsigned char ciphertext[crypto_kem_sntrup761_CIPHERTEXTBYTES]; + unsigned char secret[crypto_kem_sntrup761_BYTES]; + + if (mkdir("sntrup761_pubkey_corpus", 0777) != 0 && errno != EEXIST) + err(1, "mkdir sntrup761_pubkey_corpus"); + if (mkdir("sntrup761_ciphertext_corpus", 0777) != 0 && errno != EEXIST) + err(1, "mkdir sntrup761_ciphertext_corpus"); + + fprintf(stderr, "making: "); + for (i = 0; i < NSEEDS; i++) { + real_random = i != 0; + if (crypto_kem_sntrup761_keypair(pk, sk) != 0) + errx(1, "crypto_kem_sntrup761_keypair failed"); + write_blob("sntrup761_pubkey_corpus", i, "pk", pk, sizeof(pk)); + if (crypto_kem_sntrup761_enc(ciphertext, secret, pk) != 0) + errx(1, "crypto_kem_sntrup761_enc failed"); + write_blob("sntrup761_ciphertext_corpus", i, "ct", + ciphertext, sizeof(ciphertext)); + if (i % 20 == 0) + fprintf(stderr, "."); + } + fprintf(stderr, "\n"); + return 0; +} diff --git a/regress/misc/fuzz-harness/sntrup761_dec_fuzz.cc b/regress/misc/fuzz-harness/sntrup761_dec_fuzz.cc new file mode 100644 index 00000000000..9aecae0ad18 --- /dev/null +++ b/regress/misc/fuzz-harness/sntrup761_dec_fuzz.cc @@ -0,0 +1,74 @@ +// Basic fuzz test for depcapsulate operation, + +#include +#include +#include +#include +#include +#include +#include + +extern "C" { + +#include "crypto_api.h" +#include "hash.c" + +#undef randombytes +#define USE_SNTRUP761X25519 1 +#ifdef SNTRUP761_NO_ASM +# undef __GNUC__ +#endif +void randombytes(unsigned char *ptr, size_t l); +volatile crypto_int16 crypto_int16_optblocker = 0; +volatile crypto_int32 crypto_int32_optblocker = 0; +volatile crypto_int64 crypto_int64_optblocker = 0; +#include "sntrup761.c" + +static int real_random; + +void +randombytes(unsigned char *ptr, size_t l) +{ + if (real_random) + arc4random_buf(ptr, l); + else + memset(ptr, 0, l); +} + +void privkeys(unsigned char *zero_sk, unsigned char *rnd_sk) +{ + unsigned char pk[crypto_kem_sntrup761_PUBLICKEYBYTES]; + + real_random = 0; + if (crypto_kem_sntrup761_keypair(pk, zero_sk) != 0) + errx(1, "crypto_kem_sntrup761_keypair failed"); + real_random = 1; + if (crypto_kem_sntrup761_keypair(pk, rnd_sk) != 0) + errx(1, "crypto_kem_sntrup761_keypair failed"); +} + +int LLVMFuzzerTestOneInput(const uint8_t* input, size_t len) +{ + static bool once; + static unsigned char zero_sk[crypto_kem_sntrup761_SECRETKEYBYTES]; + static unsigned char rnd_sk[crypto_kem_sntrup761_SECRETKEYBYTES]; + unsigned char ciphertext[crypto_kem_sntrup761_CIPHERTEXTBYTES]; + unsigned char secret[crypto_kem_sntrup761_BYTES]; + + if (!once) { + privkeys(zero_sk, rnd_sk); + once = true; + } + + memset(&ciphertext, 0, sizeof(ciphertext)); + if (len > sizeof(ciphertext)) { + len = sizeof(ciphertext); + } + memcpy(ciphertext, input, len); + + (void)crypto_kem_sntrup761_dec(secret, ciphertext, zero_sk); + (void)crypto_kem_sntrup761_dec(secret, ciphertext, rnd_sk); + return 0; +} + +} // extern diff --git a/regress/misc/fuzz-harness/sntrup761_enc_fuzz.cc b/regress/misc/fuzz-harness/sntrup761_enc_fuzz.cc new file mode 100644 index 00000000000..c4ebac41f19 --- /dev/null +++ b/regress/misc/fuzz-harness/sntrup761_enc_fuzz.cc @@ -0,0 +1,57 @@ +// Basic fuzz test for encapsulate operation. + +#include +#include +#include +#include +#include +#include +#include + +extern "C" { + +#include "crypto_api.h" +#include "hash.c" + +#undef randombytes +#define USE_SNTRUP761X25519 1 +#ifdef SNTRUP761_NO_ASM +# undef __GNUC__ +#endif +void randombytes(unsigned char *ptr, size_t l); +volatile crypto_int16 crypto_int16_optblocker = 0; +volatile crypto_int32 crypto_int32_optblocker = 0; +volatile crypto_int64 crypto_int64_optblocker = 0; +#include "sntrup761.c" + +static int real_random; + +void +randombytes(unsigned char *ptr, size_t l) +{ + if (real_random) + arc4random_buf(ptr, l); + else + memset(ptr, 0, l); +} + +int LLVMFuzzerTestOneInput(const uint8_t* input, size_t len) +{ + unsigned char pk[crypto_kem_sntrup761_PUBLICKEYBYTES]; + unsigned char ciphertext[crypto_kem_sntrup761_CIPHERTEXTBYTES]; + unsigned char secret[crypto_kem_sntrup761_BYTES]; + + memset(&pk, 0, sizeof(pk)); + if (len > sizeof(pk)) { + len = sizeof(pk); + } + memcpy(pk, input, len); + + real_random = 0; + (void)crypto_kem_sntrup761_enc(ciphertext, secret, pk); + real_random = 1; + (void)crypto_kem_sntrup761_enc(ciphertext, secret, pk); + return 0; +} + +} // extern diff --git a/regress/misc/fuzz-harness/watch-sntrup761.sh b/regress/misc/fuzz-harness/watch-sntrup761.sh new file mode 100755 index 00000000000..482f831ceef --- /dev/null +++ b/regress/misc/fuzz-harness/watch-sntrup761.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +set -e +mkdir -p sntrup761_dec_fuzzing sntrup761_enc_fuzzing +(cd sntrup761_enc_fuzzing ; + ../sntrup761_enc_fuzz -jobs=48 ../sntrup761_pubkey_corpus &) +(cd sntrup761_dec_fuzzing ; + ../sntrup761_dec_fuzz -jobs=48 ../sntrup761_ciphertext_corpus &) + +while true ; do + clear + uptime + echo + echo "Findings" + ls -1 sntrup761_dec_fuzzing sntrup761_enc_fuzzing | grep -v '^fuzz-.*log$' + printf "\n\n" + printf "ciphertext_corpus: " ; ls -1 sntrup761_ciphertext_corpus | wc -l + printf " pubkey_corpus: "; ls -1 sntrup761_pubkey_corpus | wc -l + sleep 10; +done diff --git a/regress/misc/ssh-verify-attestation/Makefile b/regress/misc/ssh-verify-attestation/Makefile new file mode 100644 index 00000000000..2a797aecae4 --- /dev/null +++ b/regress/misc/ssh-verify-attestation/Makefile @@ -0,0 +1,79 @@ +# $OpenBSD: Makefile,v 1.1 2024/12/04 16:42:49 djm Exp $ + +.include +.include + +PROG= ssh-verify-attestation +NOMAN= + +SSHREL=../../../../../usr.bin/ssh +.PATH: ${.CURDIR}/${SSHREL} + +SRCS=ssh-verify-attestation.c +# From usr.bin/ssh +SRCS+=sshbuf-getput-basic.c sshbuf-getput-crypto.c sshbuf-misc.c sshbuf.c +SRCS+=sshbuf-io.c atomicio.c sshkey.c authfile.c cipher.c log.c ssh-rsa.c +SRCS+=ssh-dss.c ssh-ecdsa.c ssh-ed25519.c mac.c umac.c umac128.c hmac.c misc.c +SRCS+=ssherr.c uidswap.c cleanup.c xmalloc.c match.c krl.c fatal.c +SRCS+=addr.c addrmatch.c bitmap.c +SRCS+=ed25519.c hash.c +SRCS+=cipher-chachapoly.c chacha.c poly1305.c ssh-ecdsa-sk.c ssh-sk.c +SRCS+=ssh-ed25519-sk.c sk-usbhid.c + +SRCS+=digest-openssl.c +#SRCS+=digest-libc.c +SRCS+=utf8.c + +OPENSSL?= yes + +.if (${OPENSSL:L} == "yes") +CFLAGS+= -DWITH_OPENSSL +.endif + +# enable warnings +WARNINGS=Yes + +DEBUG=-g +CFLAGS+= -fstack-protector-all +CDIAGFLAGS= -Wall +CDIAGFLAGS+= -Wextra +CDIAGFLAGS+= -Werror +CDIAGFLAGS+= -Wchar-subscripts +CDIAGFLAGS+= -Wcomment +CDIAGFLAGS+= -Wformat +CDIAGFLAGS+= -Wformat-security +CDIAGFLAGS+= -Wimplicit +CDIAGFLAGS+= -Winline +CDIAGFLAGS+= -Wmissing-declarations +CDIAGFLAGS+= -Wmissing-prototypes +CDIAGFLAGS+= -Wparentheses +CDIAGFLAGS+= -Wpointer-arith +CDIAGFLAGS+= -Wreturn-type +CDIAGFLAGS+= -Wshadow +CDIAGFLAGS+= -Wsign-compare +CDIAGFLAGS+= -Wstrict-aliasing +CDIAGFLAGS+= -Wstrict-prototypes +CDIAGFLAGS+= -Wswitch +CDIAGFLAGS+= -Wtrigraphs +CDIAGFLAGS+= -Wuninitialized +CDIAGFLAGS+= -Wunused +CDIAGFLAGS+= -Wno-unused-parameter +.if ${COMPILER_VERSION:L} != "gcc3" +CDIAGFLAGS+= -Wold-style-definition +.endif + +CFLAGS+=-I${.CURDIR}/${SSHREL} + +.if (${OPENSSL:L} == "yes") +LDADD+= -lcrypto +DPADD+= ${LIBCRYPTO} +.endif + +LDADD+= -lfido2 -lcbor +DPADD+= ${LIBFIDO2} ${LIBCBOR} + +LDADD+= -lutil +DPADD+= ${LIBUTIL} + +.include + diff --git a/regress/misc/ssh-verify-attestation/ssh-verify-attestation.c b/regress/misc/ssh-verify-attestation/ssh-verify-attestation.c new file mode 100644 index 00000000000..4d82a039058 --- /dev/null +++ b/regress/misc/ssh-verify-attestation/ssh-verify-attestation.c @@ -0,0 +1,433 @@ +/* $OpenBSD: ssh-verify-attestation.c,v 1.2 2024/12/06 10:37:42 djm Exp $ */ +/* + * Copyright (c) 2022-2024 Damien Miller + * + * Permission to use, copy, modify, and 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. + */ + +/* + * This is a small program to verify FIDO attestation objects that + * ssh-keygen(1) can record when enrolling a FIDO key. It requires that + * the attestation object and challenge used when creating the key be + * recorded. + * + * Example usage: + * + * $ # Generate a random challenge. + * $ dd if=/dev/urandom of=key_ecdsa_sk.challenge bs=32 count=1 + * $ # Generate a key, record the attestation blob. + * $ ssh-keygen -f key_ecdsa_sk -t ecdsa-sk \ + * -Ochallenge=key_ecdsa_sk.challenge \ + * -Owrite-attestation=key_ecdsa_sk.attest -N '' + * $ # Validate the challenge (-A = print attestation CA cert) + * $ ./obj/ssh-verify-attestation -A key_ecdsa_sk key_ecdsa_sk.challenge \ + * key_ecdsa_sk.attest + * + * Limitations/TODO: + * + * 1) It doesn't automatically detect the attestation statement format. It + * assumes the "packed" format used by FIDO2 keys. If that doesn't work, + * then try using the -U option to select the "fido-u2f" format. + * 2) It makes assumptions about RK, UV, etc status of the key/cred. + * 3) Probably bugs. + * + * Thanks to Markus Friedl and Pedro Martelletto for help getting this + * working. + */ + +#include "includes.h" + +#include +#include +#include +#include +#include +#include + +#include "xmalloc.h" +#include "log.h" +#include "sshbuf.h" +#include "sshkey.h" +#include "authfile.h" +#include "ssherr.h" +#include "misc.h" +#include "digest.h" +#include "crypto_api.h" + +#include +#include +#include +#include +#include +#include + +extern char *__progname; + +#define ATTEST_MAGIC "ssh-sk-attest-v01" + +static int +prepare_fido_cred(fido_cred_t *cred, int credtype, const char *attfmt, + const char *rp_id, struct sshbuf *b, const struct sshbuf *challenge, + struct sshbuf **attestation_certp) +{ + struct sshbuf *attestation_cert = NULL, *sig = NULL, *authdata = NULL; + char *magic = NULL; + int r = SSH_ERR_INTERNAL_ERROR; + + *attestation_certp = NULL; + + /* Make sure it's the format we're expecting */ + if ((r = sshbuf_get_cstring(b, &magic, NULL)) != 0) { + error_fr(r, "parse header"); + goto out; + } + if (strcmp(magic, ATTEST_MAGIC) != 0) { + error_f("unsupported format"); + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + /* Parse the remaining fields */ + if ((r = sshbuf_froms(b, &attestation_cert)) != 0 || + (r = sshbuf_froms(b, &sig)) != 0 || + (r = sshbuf_froms(b, &authdata)) != 0 || + (r = sshbuf_get_u32(b, NULL)) != 0 || /* reserved flags */ + (r = sshbuf_get_string_direct(b, NULL, NULL)) != 0) { /* reserved */ + error_fr(r, "parse body"); + goto out; + } + debug3_f("attestation cert len=%zu, sig len=%zu, " + "authdata len=%zu challenge len=%zu", sshbuf_len(attestation_cert), + sshbuf_len(sig), sshbuf_len(authdata), sshbuf_len(challenge)); + + fido_cred_set_type(cred, credtype); + fido_cred_set_fmt(cred, attfmt); + fido_cred_set_clientdata(cred, sshbuf_ptr(challenge), + sshbuf_len(challenge)); + fido_cred_set_rp(cred, rp_id, NULL); + fido_cred_set_authdata(cred, sshbuf_ptr(authdata), + sshbuf_len(authdata)); + /* XXX set_extensions, set_rk, set_uv */ + fido_cred_set_x509(cred, sshbuf_ptr(attestation_cert), + sshbuf_len(attestation_cert)); + fido_cred_set_sig(cred, sshbuf_ptr(sig), sshbuf_len(sig)); + + /* success */ + *attestation_certp = attestation_cert; + attestation_cert = NULL; + r = 0; + out: + free(magic); + sshbuf_free(attestation_cert); + sshbuf_free(sig); + sshbuf_free(authdata); + return r; +} + +static uint8_t * +get_pubkey_from_cred_ecdsa(const fido_cred_t *cred, size_t *pubkey_len) +{ + const uint8_t *ptr; + uint8_t *pubkey = NULL, *ret = NULL; + BIGNUM *x = NULL, *y = NULL; + EC_POINT *q = NULL; + EC_GROUP *g = NULL; + + if ((x = BN_new()) == NULL || + (y = BN_new()) == NULL || + (g = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)) == NULL || + (q = EC_POINT_new(g)) == NULL) { + error_f("libcrypto setup failed"); + goto out; + } + if ((ptr = fido_cred_pubkey_ptr(cred)) == NULL) { + error_f("fido_cred_pubkey_ptr failed"); + goto out; + } + if (fido_cred_pubkey_len(cred) != 64) { + error_f("bad fido_cred_pubkey_len %zu", + fido_cred_pubkey_len(cred)); + goto out; + } + + if (BN_bin2bn(ptr, 32, x) == NULL || + BN_bin2bn(ptr + 32, 32, y) == NULL) { + error_f("BN_bin2bn failed"); + goto out; + } + if (EC_POINT_set_affine_coordinates_GFp(g, q, x, y, NULL) != 1) { + error_f("EC_POINT_set_affine_coordinates_GFp failed"); + goto out; + } + *pubkey_len = EC_POINT_point2oct(g, q, + POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); + if (*pubkey_len == 0 || *pubkey_len > 2048) { + error_f("bad pubkey length %zu", *pubkey_len); + goto out; + } + if ((pubkey = malloc(*pubkey_len)) == NULL) { + error_f("malloc pubkey failed"); + goto out; + } + if (EC_POINT_point2oct(g, q, POINT_CONVERSION_UNCOMPRESSED, + pubkey, *pubkey_len, NULL) == 0) { + error_f("EC_POINT_point2oct failed"); + goto out; + } + /* success */ + ret = pubkey; + pubkey = NULL; + out: + free(pubkey); + EC_POINT_free(q); + EC_GROUP_free(g); + BN_clear_free(x); + BN_clear_free(y); + return ret; +} + +/* copied from sshsk_ecdsa_assemble() */ +static int +cred_matches_key_ecdsa(const fido_cred_t *cred, const struct sshkey *k) +{ + struct sshkey *key = NULL; + struct sshbuf *b = NULL; + EC_KEY *ec = NULL; + uint8_t *pubkey = NULL; + size_t pubkey_len; + int r; + + if ((key = sshkey_new(KEY_ECDSA_SK)) == NULL) { + error_f("sshkey_new failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + key->ecdsa_nid = NID_X9_62_prime256v1; + if ((key->pkey = EVP_PKEY_new()) == NULL || + (ec = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL || + (b = sshbuf_new()) == NULL) { + error_f("allocation failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((pubkey = get_pubkey_from_cred_ecdsa(cred, &pubkey_len)) == NULL) { + error_f("get_pubkey_from_cred_ecdsa failed"); + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + if ((r = sshbuf_put_string(b, pubkey, pubkey_len)) != 0) { + error_fr(r, "sshbuf_put_string"); + goto out; + } + if ((r = sshbuf_get_eckey(b, ec)) != 0) { + error_fr(r, "parse"); + r = SSH_ERR_INVALID_FORMAT; + goto out; + } + if (sshkey_ec_validate_public(EC_KEY_get0_group(ec), + EC_KEY_get0_public_key(ec)) != 0) { + error("Authenticator returned invalid ECDSA key"); + r = SSH_ERR_KEY_INVALID_EC_VALUE; + goto out; + } + if (EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) { + /* XXX assume it is a allocation error */ + error_f("allocation failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + key->sk_application = xstrdup(k->sk_application); /* XXX */ + if (!sshkey_equal_public(key, k)) { + error("sshkey_equal_public failed"); + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + r = 0; /* success */ + out: + EC_KEY_free(ec); + free(pubkey); + sshkey_free(key); + sshbuf_free(b); + return r; +} + + +/* copied from sshsk_ed25519_assemble() */ +static int +cred_matches_key_ed25519(const fido_cred_t *cred, const struct sshkey *k) +{ + struct sshkey *key = NULL; + const uint8_t *ptr; + int r = -1; + + if ((ptr = fido_cred_pubkey_ptr(cred)) == NULL) { + error_f("fido_cred_pubkey_ptr failed"); + goto out; + } + if (fido_cred_pubkey_len(cred) != ED25519_PK_SZ) { + error_f("bad fido_cred_pubkey_len %zu", + fido_cred_pubkey_len(cred)); + goto out; + } + + if ((key = sshkey_new(KEY_ED25519_SK)) == NULL) { + error_f("sshkey_new failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((key->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { + error_f("malloc failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + memcpy(key->ed25519_pk, ptr, ED25519_PK_SZ); + key->sk_application = xstrdup(k->sk_application); /* XXX */ + if (!sshkey_equal_public(key, k)) { + error("sshkey_equal_public failed"); + r = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + r = 0; /* success */ + out: + sshkey_free(key); + return r; +} + +static int +cred_matches_key(const fido_cred_t *cred, const struct sshkey *k) +{ + switch (sshkey_type_plain(k->type)) { + case KEY_ECDSA_SK: + switch (k->ecdsa_nid) { + case NID_X9_62_prime256v1: + return cred_matches_key_ecdsa(cred, k); + break; + default: + fatal("Unsupported ECDSA key size"); + } + break; + case KEY_ED25519_SK: + return cred_matches_key_ed25519(cred, k); + default: + error_f("key type %s not supported", sshkey_type(k)); + return -1; + } +} + +int +main(int argc, char **argv) +{ + LogLevel log_level = SYSLOG_LEVEL_INFO; + int r, ch, credtype = -1; + struct sshkey *k = NULL; + struct sshbuf *attestation = NULL, *challenge = NULL; + struct sshbuf *attestation_cert = NULL; + char *fp; + const char *attfmt = "packed", *style = NULL; + fido_cred_t *cred = NULL; + int write_attestation_cert = 0; + extern int optind; + /* extern char *optarg; */ + + ERR_load_crypto_strings(); + + sanitise_stdfd(); + log_init(__progname, log_level, SYSLOG_FACILITY_AUTH, 1); + + while ((ch = getopt(argc, argv, "UAv")) != -1) { + switch (ch) { + case 'U': + attfmt = "fido-u2f"; + break; + case 'A': + write_attestation_cert = 1; + break; + case 'v': + if (log_level == SYSLOG_LEVEL_ERROR) + log_level = SYSLOG_LEVEL_DEBUG1; + else if (log_level < SYSLOG_LEVEL_DEBUG3) + log_level++; + break; + default: + goto usage; + } + } + log_init(__progname, log_level, SYSLOG_FACILITY_AUTH, 1); + argv += optind; + argc -= optind; + + if (argc < 3) { + usage: + fprintf(stderr, "usage: %s [-vAU] " + "pubkey challenge attestation-blob\n", __progname); + exit(1); + } + if ((r = sshkey_load_public(argv[0], &k, NULL)) != 0) + fatal_r(r, "load key %s", argv[0]); + if ((fp = sshkey_fingerprint(k, SSH_FP_HASH_DEFAULT, + SSH_FP_DEFAULT)) == NULL) + fatal("sshkey_fingerprint failed"); + debug2("key %s: %s %s", argv[2], sshkey_type(k), fp); + free(fp); + if ((r = sshbuf_load_file(argv[1], &challenge)) != 0) + fatal_r(r, "load challenge %s", argv[1]); + if ((r = sshbuf_load_file(argv[2], &attestation)) != 0) + fatal_r(r, "load attestation %s", argv[2]); + if ((cred = fido_cred_new()) == NULL) + fatal("fido_cred_new failed"); + + switch (sshkey_type_plain(k->type)) { + case KEY_ECDSA_SK: + switch (k->ecdsa_nid) { + case NID_X9_62_prime256v1: + credtype = COSE_ES256; + break; + default: + fatal("Unsupported ECDSA key size"); + } + break; + case KEY_ED25519_SK: + credtype = COSE_EDDSA; + break; + default: + fatal("unsupported key type %s", sshkey_type(k)); + } + + if ((r = prepare_fido_cred(cred, credtype, attfmt, k->sk_application, + attestation, challenge, &attestation_cert)) != 0) + fatal_r(r, "prepare_fido_cred %s", argv[2]); + if (fido_cred_x5c_ptr(cred) != NULL) { + debug("basic attestation"); + if ((r = fido_cred_verify(cred)) != FIDO_OK) + fatal("basic attestation failed"); + style = "basic"; + } else { + debug("self attestation"); + if ((r = fido_cred_verify_self(cred)) != FIDO_OK) + fatal("self attestation failed"); + style = "self"; + } + if (cred_matches_key(cred, k) != 0) + fatal("cred authdata does not match key"); + + fido_cred_free(&cred); + + if (write_attestation_cert) { + PEM_write(stdout, "CERTIFICATE", NULL, + sshbuf_ptr(attestation_cert), sshbuf_len(attestation_cert)); + } + sshbuf_free(attestation_cert); + + logit("%s: verified %s attestation", argv[2], style); + + return (0); +} diff --git a/regress/multiplex.sh b/regress/multiplex.sh index 32235cfd64f..6207ed472bc 100644 --- a/regress/multiplex.sh +++ b/regress/multiplex.sh @@ -1,4 +1,4 @@ -# $OpenBSD: multiplex.sh,v 1.36 2023/03/01 09:29:32 dtucker Exp $ +# $OpenBSD: multiplex.sh,v 1.37 2024/07/19 04:33:36 djm Exp $ # Placed in the Public Domain. make_tmpdir @@ -62,19 +62,20 @@ if [ $? -ne 0 ]; then fail "environment not found" fi - -verbose "test $tid: transfer" -rm -f ${COPY} -trace "ssh transfer over multiplexed connection and check result" -${SSH} -F $OBJ/ssh_config -S$CTL otherhost cat ${DATA} > ${COPY} -test -f ${COPY} || fail "ssh -Sctl: failed copy ${DATA}" -cmp ${DATA} ${COPY} || fail "ssh -Sctl: corrupted copy of ${DATA}" - -rm -f ${COPY} -trace "ssh transfer over multiplexed connection and check result" -${SSH} -F $OBJ/ssh_config -S $CTL otherhost cat ${DATA} > ${COPY} -test -f ${COPY} || fail "ssh -S ctl: failed copy ${DATA}" -cmp ${DATA} ${COPY} || fail "ssh -S ctl: corrupted copy of ${DATA}" +for mode in "" "-Oproxy"; do + verbose "test $tid: transfer $mode" + rm -f ${COPY} + trace "ssh transfer over $mode multiplexed connection and check result" + ${SSH} $mode -F $OBJ/ssh_config -S$CTL otherhost cat ${DATA} > ${COPY} + test -f ${COPY} || fail "ssh -Sctl: failed copy ${DATA}" + cmp ${DATA} ${COPY} || fail "ssh -Sctl: corrupted copy of ${DATA}" + + rm -f ${COPY} + trace "ssh transfer over $mode multiplexed connection and check result" + ${SSH} $mode -F $OBJ/ssh_config -S $CTL otherhost cat ${DATA} > ${COPY} + test -f ${COPY} || fail "ssh -S ctl: failed copy ${DATA}" + cmp ${DATA} ${COPY} || fail "ssh -S ctl: corrupted copy of ${DATA}" +done rm -f ${COPY} trace "sftp transfer over multiplexed connection and check result" diff --git a/regress/percent.sh b/regress/percent.sh index 354854f97d5..7ce9e8a1dc3 100644 --- a/regress/percent.sh +++ b/regress/percent.sh @@ -1,4 +1,4 @@ -# $OpenBSD: percent.sh,v 1.17 2023/03/27 03:56:50 dtucker Exp $ +# $OpenBSD: percent.sh,v 1.21 2025/04/08 23:10:46 djm Exp $ # Placed in the Public Domain. tid="percent expansions" @@ -29,6 +29,23 @@ trial() somehost true got=`cat $OBJ/actual` ;; + user|user-l|user-at) + if [ "$arg" = '%r' ] || [ "$arg" = '%C' ]; then + # User does not support %r, ie itself or %C. Skip test. + got="$expect" + elif [ "$i" = "user" ]; then + got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg" -G \ + remuser@somehost | awk '$1=="'$opt'"{print $2}'` + elif [ "$i" = "user-l" ]; then + # Also test ssh -l + got=`${SSH} -F $OBJ/ssh_proxy -l "$arg" -G \ + somehost | awk '$1=="'user'"{print $2}'` + elif [ "$i" = "user-at" ]; then + # Also test user@host + got=`${SSH} -F $OBJ/ssh_proxy -G "$arg@somehost" | \ + awk '$1=="'user'"{print $2}'` + fi + ;; userknownhostsfile) # Move the userknownhosts file to what the expansion says, # make sure ssh works then put it back. @@ -51,6 +68,18 @@ trial() remuser@somehost | awk '$1=="'$opt'"{print $2" "$3}'` expect="/$expect /$expect" ;; + setenv) + # First make sure we don't expand variable names. + got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg=TESTVAL" -G \ + remuser@somehost | awk '$1=="'$opt'"{print $2}'` + if [ "$got" != "$arg=TESTVAL" ]; then + fatal "incorrectly expanded setenv variable name" + fi + # Now check that the value expands as expected. + got=`${SSH} -F $OBJ/ssh_proxy -o $opt=TESTVAL="$arg" -G \ + remuser@somehost | awk '$1=="'$opt'"{print $2}'` + got=`echo "$got" | sed 's/^TESTVAL=//'` + ;; *) got=`${SSH} -F $OBJ/ssh_proxy -o $opt="$arg" -G \ remuser@somehost | awk '$1=="'$opt'"{print $2}'` @@ -62,7 +91,7 @@ trial() for i in matchexec localcommand remotecommand controlpath identityagent \ forwardagent localforward remoteforward revokedhostkeys \ - userknownhostsfile; do + user user-l user-at setenv userknownhostsfile; do verbose $tid $i percent case "$i" in localcommand|userknownhostsfile) @@ -77,7 +106,7 @@ for i in matchexec localcommand remotecommand controlpath identityagent \ fi # Matches implementation in readconf.c:ssh_connection_hash() if [ ! -z "${OPENSSL_BIN}" ]; then - HASH=`printf "${HOSTNAME}127.0.0.1${PORT}$REMUSER" | + HASH=`printf "${HOSTNAME}127.0.0.1${PORT}${REMUSER}" | $OPENSSL_BIN sha1 | cut -f2 -d' '` trial $i '%C' $HASH fi @@ -92,8 +121,9 @@ for i in matchexec localcommand remotecommand controlpath identityagent \ trial $i '%r' $REMUSER trial $i '%u' $USER # We can't specify a full path outside the regress dir, so skip tests - # containing %d for UserKnownHostsFile - if [ "$i" != "userknownhostsfile" ]; then + # containing %d for UserKnownHostsFile, and %r can't refer to itself. + if [ "$i" != "userknownhostsfile" ] && [ "$i" != "user" ] && \ + [ "$i" != "user-l" ] && [ "$i" != "user-at" ]; then trial $i '%d' $HOME in='%%/%i/%h/%d/%L/%l/%n/%p/%r/%u' out="%/$USERID/127.0.0.1/$HOME/$HOST/$HOSTNAME/somehost/$PORT/$REMUSER/$USER" @@ -108,7 +138,7 @@ done # Subset of above since we don't expand shell-style variables on anything that # runs a command because the shell will expand those. for i in controlpath identityagent forwardagent localforward remoteforward \ - userknownhostsfile; do + user user-l user-at setenv userknownhostsfile; do verbose $tid $i dollar FOO=bar export FOO diff --git a/regress/rekey.sh b/regress/rekey.sh index 86bef47c69e..828e6d0826e 100644 --- a/regress/rekey.sh +++ b/regress/rekey.sh @@ -1,87 +1,125 @@ -# $OpenBSD: rekey.sh,v 1.20 2024/05/22 04:20:00 djm Exp $ +# $OpenBSD: rekey.sh,v 1.30 2024/08/28 12:08:26 djm Exp $ # Placed in the Public Domain. tid="rekey" LOG=${TEST_SSH_LOGFILE} +COPY2=$OBJ/copy2 rm -f ${LOG} cp $OBJ/sshd_proxy $OBJ/sshd_proxy_bak +echo "Compression no" >> $OBJ/ssh_proxy +echo "RekeyLimit 256k" >> $OBJ/ssh_proxy +echo "KexAlgorithms curve25519-sha256" >> ssh_proxy + # Test rekeying based on data volume only. -# Arguments will be passed to ssh. +# Arguments: rekeylimit, kex method, optional remaining opts are passed to ssh. ssh_data_rekeying() { + _bytes=$1 ; shift _kexopt=$1 ; shift _opts="$@" + if test -z "$_bytes"; then + _bytes=32k + fi if ! test -z "$_kexopt" ; then cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "$_kexopt" >> $OBJ/sshd_proxy _opts="$_opts -o$_kexopt" fi - rm -f ${COPY} ${LOG} - _opts="$_opts -oCompression=no" + case "$_kexopt" in + MACs=*) + # default chacha20-poly1305 cipher has implicit MAC + _opts="$_opts -oCiphers=aes128-ctr" ;; + esac + trace bytes $_bytes kex $_kexopt opts $_opts + rm -f ${COPY} ${COPY2} ${LOG} + # Create data file just big enough to reach rekey threshold. + dd if=${DATA} of=${COPY} bs=$_bytes count=1 2>/dev/null if [ "$os" == "windows" ]; then - cat ${DATA} | ${SSH} $_opts -v -F $OBJ/ssh_proxy somehost "cat > ${COPY}" + cat ${COPY} | ${SSH} $_opts -vv \ + -oRekeyLimit=$_bytes -F $OBJ/ssh_proxy somehost "cat > ${COPY2}" else - ${SSH} <${DATA} $_opts -v -F $OBJ/ssh_proxy somehost "cat > ${COPY}" + ${SSH} <${COPY} $_opts -vv \ + -oRekeyLimit=$_bytes -F $OBJ/ssh_proxy somehost "cat >${COPY2}" fi if [ $? -ne 0 ]; then fail "ssh failed ($@)" fi - cmp ${DATA} ${COPY} || fail "corrupted copy ($@)" + cmp ${COPY} ${COPY2} || fail "corrupted copy ($@)" n=`grep 'NEWKEYS sent' ${LOG} | wc -l` n=`expr $n - 1` + _want=`echo $_kexopt | cut -f2 -d=` + _got="" + case "$_kexopt" in + KexAlgorithms=*) + _got=`awk '/kex: algorithm: /{print $4}' ${LOG} | \ + tr -d '\r' | sort -u` ;; + Ciphers=*) + _got=`awk '/kex: client->server cipher:/{print $5}' ${LOG} | \ + tr -d '\r' | sort -u` ;; + MACs=*) + _got=`awk '/kex: client->server cipher:/{print $7}' ${LOG} | \ + tr -d '\r' | sort -u` ;; + esac + if [ "$_want" != "$_got" ]; then + fail "unexpected algorithm, want $_want, got $_got" + fi trace "$n rekeying(s)" if [ $n -lt 1 ]; then fail "no rekeying occurred ($@)" fi + cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy } increase_datafile_size 300 opts="" -for i in `${SSH} -Q kex`; do + +# Filter out duplicate curve algo +kexs=`${SSH} -Q kex | grep -v curve25519-sha256@libssh.org` +ciphers=`${SSH} -Q cipher` +macs=`${SSH} -Q mac` + +for i in $kexs; do opts="$opts KexAlgorithms=$i" done -for i in `${SSH} -Q cipher`; do +for i in $ciphers; do opts="$opts Ciphers=$i" done -for i in `${SSH} -Q mac`; do +for i in $macs; do opts="$opts MACs=$i" done for opt in $opts; do verbose "client rekey $opt" - ssh_data_rekeying "$opt" -oRekeyLimit=256k + if ${SSH} -Q cipher-auth | sed 's/^/Ciphers=/' | \ + grep $opt >/dev/null; then + trace AEAD cipher, testing all KexAlgorithms + for kex in $kexs; do + ssh_data_rekeying "" "KexAlgorithms=$kex" "-o$opt" + done + else + ssh_data_rekeying "" "$opt" + fi done -# AEAD ciphers are magical so test with all KexAlgorithms -if ${SSH} -Q cipher-auth | grep '^.*$' >/dev/null 2>&1 ; then - for c in `${SSH} -Q cipher-auth`; do - for kex in `${SSH} -Q kex`; do - verbose "client rekey $c $kex" - ssh_data_rekeying "KexAlgorithms=$kex" -oRekeyLimit=256k -oCiphers=$c - done - done -fi - for s in 16 1k 128k 256k; do verbose "client rekeylimit ${s}" - ssh_data_rekeying "" -oCompression=no -oRekeyLimit=$s + ssh_data_rekeying "$s" "" done for s in 5 10; do verbose "client rekeylimit default ${s}" rm -f ${COPY} ${LOG} if [ "$os" == "windows" ]; then - cat ${DATA} | ${SSH} -oCompression=no -oRekeyLimit="default $s" -F \ + cat ${DATA} | ${SSH} -oRekeyLimit="default $s" -F \ $OBJ/ssh_proxy somehost "cat >${COPY};sleep $s;sleep 10" else - ${SSH} < ${DATA} -oCompression=no -oRekeyLimit="default $s" -F \ + ${SSH} < ${DATA} -oRekeyLimit="default $s" -F \ $OBJ/ssh_proxy somehost "cat >${COPY};sleep $s;sleep 10" fi - if [ $? -ne 0 ]; then fail "ssh failed" fi @@ -97,7 +135,7 @@ done for s in 5 10; do verbose "client rekeylimit default ${s} no data" rm -f ${COPY} ${LOG} - ${SSH} -oCompression=no -oRekeyLimit="default $s" -F \ + ${SSH} -oRekeyLimit="default $s" -F \ $OBJ/ssh_proxy somehost "sleep $s;sleep 10" if [ $? -ne 0 ]; then fail "ssh failed" @@ -114,13 +152,13 @@ for s in 16 1k 128k 256k; do verbose "server rekeylimit ${s}" cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "rekeylimit ${s}" >>$OBJ/sshd_proxy - rm -f ${COPY} ${LOG} - ${SSH} -oCompression=no -F $OBJ/ssh_proxy somehost "cat ${DATA}" \ - > ${COPY} + rm -f ${COPY} ${COPY2} ${LOG} + dd if=${DATA} of=${COPY} bs=$s count=1 2>/dev/null + ${SSH} -F $OBJ/ssh_proxy somehost "cat ${COPY}" >${COPY2} if [ $? -ne 0 ]; then fail "ssh failed" fi - cmp ${DATA} ${COPY} || fail "corrupted copy" + cmp ${COPY} ${COPY2} || fail "corrupted copy" n=`grep 'NEWKEYS sent' ${LOG} | wc -l` n=`expr $n - 1` trace "$n rekeying(s)" @@ -134,7 +172,7 @@ for s in 5 10; do cp $OBJ/sshd_proxy_bak $OBJ/sshd_proxy echo "rekeylimit default ${s}" >>$OBJ/sshd_proxy rm -f ${COPY} ${LOG} - ${SSH} -oCompression=no -F $OBJ/ssh_proxy somehost "sleep $s;sleep 10" + ${SSH} -F $OBJ/ssh_proxy somehost "sleep $s;sleep 10" if [ $? -ne 0 ]; then fail "ssh failed" fi @@ -146,9 +184,8 @@ for s in 5 10; do fi done -verbose "rekeylimit parsing" +verbose "rekeylimit parsing: bytes" for size in 16 1k 1K 1m 1M 1g 1G 4G 8G; do - for time in 1 1m 1M 1h 1H 1d 1D 1w 1W; do case $size in 16) bytes=16 ;; 1k|1K) bytes=1024 ;; @@ -157,6 +194,15 @@ for size in 16 1k 1K 1m 1M 1g 1G 4G 8G; do 4g|4G) bytes=4294967296 ;; 8g|8G) bytes=8589934592 ;; esac + b=`${SSH} -G -o "rekeylimit $size" -F $OBJ/ssh_proxy host | \ + awk '/rekeylimit/{print $2}'` + if [ "$bytes" != "$b" ]; then + fatal "rekeylimit size: expected $bytes bytes got $b" + fi +done + +verbose "rekeylimit parsing: time" +for time in 1 1m 1M 1h 1H 1d 1D 1w 1W; do case $time in 1) seconds=1 ;; 1m|1M) seconds=60 ;; @@ -164,21 +210,14 @@ for size in 16 1k 1K 1m 1M 1g 1G 4G 8G; do 1d|1D) seconds=86400 ;; 1w|1W) seconds=604800 ;; esac - - b=`$SUDO ${SSHD} -T -o "rekeylimit $size $time" -f $OBJ/sshd_proxy | \ - awk '/rekeylimit/{print $2}'` - s=`$SUDO ${SSHD} -T -o "rekeylimit $size $time" -f $OBJ/sshd_proxy | \ + s=`${SSH} -G -o "rekeylimit default $time" -F $OBJ/ssh_proxy host | \ awk '/rekeylimit/{print $3}'` if [ "$os" == "windows" ]; then s=${s/$'\r'/} # Remove CR (carriage return) fi - if [ "$bytes" != "$b" ]; then - fatal "rekeylimit size: expected $bytes bytes got $b" - fi if [ "$seconds" != "$s" ]; then fatal "rekeylimit time: expected $time seconds got $s" fi - done done -rm -f ${COPY} ${DATA} +rm -f ${COPY} ${COPY2} ${DATA} diff --git a/regress/servcfginclude.sh b/regress/servcfginclude.sh index eebbe4cd900..36ebcde1b6f 100644 --- a/regress/servcfginclude.sh +++ b/regress/servcfginclude.sh @@ -4,14 +4,14 @@ tid="server config include" cat > $OBJ/sshd_config.i << _EOF HostKey $OBJ/host.ssh-ed25519 -Match host a +Match host=a Banner /aa Match host b Banner /bb Include $OBJ/sshd_config.i.* # comment -Match host c +Match host=c Include $OBJ/sshd_config.i.* # comment Banner /cc @@ -25,7 +25,7 @@ Match Host e Banner /ee Include $OBJ/sshd_config.i.* -Match Host f +Match Host=f Include $OBJ/sshd_config.i.* Banner /ff @@ -47,13 +47,13 @@ Match host b Match host c Banner /ccc -Match Host d +Match Host=d Banner /ddd Match Host e Banner /eee -Match Host f +Match Host=f Banner /fff _EOF @@ -61,13 +61,13 @@ cat > $OBJ/sshd_config.i.2 << _EOF Match host a Banner /aaaa -Match host b +Match host=b Banner /bbbb Match host c # comment Banner /cccc -Match Host d +Match Host=d Banner /dddd Match Host e diff --git a/regress/sftp-resume.sh b/regress/sftp-resume.sh new file mode 100644 index 00000000000..f4fe8f9281d --- /dev/null +++ b/regress/sftp-resume.sh @@ -0,0 +1,43 @@ +# $OpenBSD: sftp-resume.sh,v 1.2 2025/03/11 09:06:50 dtucker Exp $ +# Placed in the Public Domain. + +tid="sftp resume" + +CLIENT_LOG=${OBJ}/sftp.log + +# We test up to 1MB, ensure source data is large enough. +increase_datafile_size 1200 + +for cmd in put get; do + verbose "$tid: ${cmd}" + for size in 0 1 1k 1m size-1 same; do + trace "$tid: test ${cmd} ${size}" + rm -rf ${COPY}.1 ${COPY}.2 + cp ${DATA} ${COPY}.1 + + # Set up requested source and destination file sizes. + case "${size}" in + 0) touch ${COPY}.2 + ;; + size-1) dd if=${DATA} of=${COPY}.1 bs=1024 count=1 >/dev/null 2>&1 + dd if=${DATA} of=${COPY}.2 bs=1023 count=1 >/dev/null 2>&1 + ;; + same) cp ${DATA} ${COPY}.2 + ;; + 1m) dd if=${COPY}.1 of=${COPY}.2 bs=1k count=1k >/dev/null 2<&1 + ;; + *) dd if=${COPY}.1 of=${COPY}.2 bs=${size} count=1 >/dev/null 2>&1 + ;; + esac + + # Perform copy and check. + echo "${cmd} -a ${COPY}.1 ${COPY}.2" | \ + ${SFTP} -D ${SFTPSERVER} -vvv >${CLIENT_LOG} 2>&1 \ + || fail "${cmd} failed" + cmp ${COPY}.1 ${COPY}.2 || fail "corrupted copy after ${cmd} ${size}" + grep "reordered" ${CLIENT_LOG} >/dev/null && \ + fail "server reordered requests ${cmd} ${size}" + done +done + +rm -rf ${COPY}.1 ${COPY}.2 diff --git a/regress/sshfp-connect.sh b/regress/sshfp-connect.sh index f78646922ef..3c73a35d05d 100644 --- a/regress/sshfp-connect.sh +++ b/regress/sshfp-connect.sh @@ -1,4 +1,4 @@ -# $OpenBSD: sshfp-connect.sh,v 1.4 2021/09/01 00:50:27 dtucker Exp $ +# $OpenBSD: sshfp-connect.sh,v 1.5 2025/03/11 11:46:44 dtucker Exp $ # Placed in the Public Domain. # This test requires external setup and thus is skipped unless @@ -29,6 +29,12 @@ if ! $SSH -Q key-plain | grep ssh-rsa >/dev/null; then elif [ -z "${TEST_SSH_SSHFP_DOMAIN}" ]; then skip "TEST_SSH_SSHFP_DOMAIN not set." else + # Prime any DNS caches and resolvers. + for i in sshtest sshtest-sha1 sshtest-sha256; do + host -t sshfp ${i}.${TEST_SSH_SSHFP_DOMAIN} >/dev/null 2>&1 + host -t sshfp ${i}-bad.${TEST_SSH_SSHFP_DOMAIN} >/dev/null 2>&1 + done + # Set RSA host key to match fingerprints above. mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig $SUDO cp $SRC/rsa_openssh.prv $OBJ/host.ssh-rsa diff --git a/regress/test-exec.sh b/regress/test-exec.sh index 155b37f810a..3335f8941bd 100644 --- a/regress/test-exec.sh +++ b/regress/test-exec.sh @@ -1,4 +1,4 @@ -# $OpenBSD: test-exec.sh,v 1.119 2024/06/20 08:18:34 dtucker Exp $ +# $OpenBSD: test-exec.sh,v 1.127 2025/03/28 05:41:15 dtucker Exp $ # Placed in the Public Domain. #SUDO=sudo @@ -98,9 +98,12 @@ SFTP=sftp SFTPSERVER=/usr/libexec/openssh/sftp-server if [ "$os" == "windows" ]; then SSHD_SESSION=sshd-session.exe + SSHD_AUTH=sshd-auth.exe else SSHD_SESSION=/usr/libexec/sshd-session + SSHD_AUTH=/usr/libexec/sshd-auth fi + SCP=scp # Set by make_tmpdir() on demand (below). @@ -129,6 +132,9 @@ fi if [ "x$TEST_SSH_SSHD_SESSION" != "x" ]; then SSHD_SESSION="${TEST_SSH_SSHD_SESSION}" fi +if [ "x$TEST_SSH_SSHD_AUTH" != "x" ]; then + SSHD_AUTH="${TEST_SSH_SSHD_AUTH}" +fi if [ "x$TEST_SSH_SSHD" != "x" ]; then SSHD="${TEST_SSH_SSHD}" fi @@ -190,6 +196,11 @@ case "$SSHD" in *) SSHD=`which $SSHD` ;; esac +case "$SSH" in +/*) ;; +*) SSH=`which $SSH` ;; +esac + case "$SSHAGENT" in /*) ;; *) SSHAGENT=`which $SSHAGENT` ;; @@ -316,6 +327,7 @@ fi # -qq is equivalent and is not removed. SSHLOGWRAP=$OBJ/ssh-log-wrapper.sh # BALU todo - check if we need to pass -T flag +rm -f ${SSHLOGWRAP} if [ "$os" == "windows" ]; then # timestamp line messes up stderr-data.sh stderr-after-eof.sh # seems to be used for debugging concurrency tests (a feature unsupported on Windows currently) @@ -349,6 +361,7 @@ REAL_SSHD="$SSHD" SSH="$SSHLOGWRAP" SSHDLOGWRAP=$OBJ/sshd-log-wrapper.sh +rm -f ${SSHDLOGWRAP} cat >$SSHDLOGWRAP < $OBJ/sshd_config AcceptEnv _XXX_TEST Subsystem sftp $SFTPSERVER SshdSessionPath $SSHD_SESSION + SshdAuthPath $SSHD_AUTH PerSourcePenalties no EOF @@ -931,7 +945,8 @@ esac if test "$REGRESS_INTEROP_DROPBEAR" = "yes" ; then trace Create dropbear keys and add to authorized_keys - mkdir -p $OBJ/.dropbear + mkdir -p $OBJ/.dropbear $OBJ/.ssh + awk '{print "somehost "$2" "$3}' $OBJ/known_hosts >$OBJ/.ssh/known_hosts kt="ed25519" for i in dss rsa ecdsa; do if $SSH -Q key-plain | grep "$i" >/dev/null; then @@ -962,7 +977,7 @@ fi # This is fine for now as we don't have FIDO enabled. echo proxycommand `windows_path ${SSHD}` -i -f $OBJ_WIN_FORMAT/sshd_proxy else - echo proxycommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy + echo proxycommand ${SUDO} env SSH_SK_HELPER=\"$SSH_SK_HELPER\" ${TEST_SSH_SSHD_ENV} ${OBJ}/sshd-log-wrapper.sh -i -f $OBJ/sshd_proxy fi ) > $OBJ/ssh_proxy @@ -987,16 +1002,18 @@ start_sshd () #TODO (Code BUG) : -E is writing the data the cygwin terminal. ${SSHD} -f $OBJ/sshd_config "$@" & else - $SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" \ - ${SSHD} -f $OBJ/sshd_config "$@" -E$TEST_SSHD_LOGFILE + $SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" ${TEST_SSH_SSHD_ENV} \ + ${SSHD} -f $OBJ/sshd_config "$@" -t || fatal "sshd_config broken" + $SUDO env SSH_SK_HELPER="$SSH_SK_HELPER" ${TEST_SSH_SSHD_ENV} \ + ${SSHD} -f $OBJ/sshd_config "$@" -E$TEST_SSHD_LOGFILE fi - trace "wait for sshd" i=0; while [ ! -f $PIDFILE -a $i -lt 10 ]; do i=`expr $i + 1` sleep $i done + rm -f ${TEST_SSHD_LOGFILE} ln -f -s ${logfile} $TEST_SSHD_LOGFILE test -f $PIDFILE || fatal "no sshd running on port $PORT" diff --git a/regress/unittests/kex/Makefile b/regress/unittests/kex/Makefile index 3c898408f19..ca4f0ee3863 100644 --- a/regress/unittests/kex/Makefile +++ b/regress/unittests/kex/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.15 2024/05/19 19:10:01 anton Exp $ +# $OpenBSD: Makefile,v 1.16 2024/09/09 03:13:39 djm Exp $ PROG=test_kex SRCS=tests.c test_kex.c test_proposal.c @@ -25,6 +25,7 @@ SRCS+= kexc25519.c SRCS+= smult_curve25519_ref.c SRCS+= kexgen.c SRCS+= kexsntrup761x25519.c +SRCS+= kexmlkem768x25519.c SRCS+= sntrup761.c SRCS+= utf8.c diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c index b1161ea824f..caf8f57f75d 100644 --- a/regress/unittests/kex/test_kex.c +++ b/regress/unittests/kex/test_kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_kex.c,v 1.8 2024/03/25 19:28:09 djm Exp $ */ +/* $OpenBSD: test_kex.c,v 1.9 2024/09/09 03:13:39 djm Exp $ */ /* * Regress test KEX * @@ -153,6 +153,7 @@ do_kex_with_key(char *kex, int keytype, int bits) #endif /* WITH_OPENSSL */ server2->kex->kex[KEX_C25519_SHA256] = kex_gen_server; server2->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; + server2->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; server2->kex->load_host_public_key = server->kex->load_host_public_key; server2->kex->load_host_private_key = server->kex->load_host_private_key; server2->kex->sign = server->kex->sign; @@ -207,6 +208,9 @@ kex_tests(void) do_kex("diffie-hellman-group-exchange-sha1"); do_kex("diffie-hellman-group14-sha1"); do_kex("diffie-hellman-group1-sha1"); +# ifdef USE_MLKEM768X25519 + do_kex("mlkem768x25519-sha256"); +# endif /* USE_MLKEM768X25519 */ # ifdef USE_SNTRUP761X25519 do_kex("sntrup761x25519-sha512@openssh.com"); # endif /* USE_SNTRUP761X25519 */ diff --git a/regress/unittests/sshkey/common.c b/regress/unittests/sshkey/common.c index 51b0d92e1d0..f325c2ac202 100644 --- a/regress/unittests/sshkey/common.c +++ b/regress/unittests/sshkey/common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: common.c,v 1.5 2021/12/14 21:25:27 deraadt Exp $ */ +/* $OpenBSD: common.c,v 1.6 2024/08/15 00:52:23 djm Exp $ */ /* * Helpers for key API tests * @@ -89,8 +89,8 @@ rsa_n(struct sshkey *k) const BIGNUM *n = NULL; ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->rsa, NULL); - RSA_get0_key(k->rsa, &n, NULL, NULL); + ASSERT_PTR_NE(k->pkey, NULL); + RSA_get0_key(EVP_PKEY_get0_RSA(k->pkey), &n, NULL, NULL); return n; } @@ -100,8 +100,8 @@ rsa_e(struct sshkey *k) const BIGNUM *e = NULL; ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->rsa, NULL); - RSA_get0_key(k->rsa, NULL, &e, NULL); + ASSERT_PTR_NE(k->pkey, NULL); + RSA_get0_key(EVP_PKEY_get0_RSA(k->pkey), NULL, &e, NULL); return e; } @@ -111,8 +111,8 @@ rsa_p(struct sshkey *k) const BIGNUM *p = NULL; ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->rsa, NULL); - RSA_get0_factors(k->rsa, &p, NULL); + ASSERT_PTR_NE(EVP_PKEY_get0_RSA(k->pkey), NULL); + RSA_get0_factors(EVP_PKEY_get0_RSA(k->pkey), &p, NULL); return p; } @@ -122,8 +122,8 @@ rsa_q(struct sshkey *k) const BIGNUM *q = NULL; ASSERT_PTR_NE(k, NULL); - ASSERT_PTR_NE(k->rsa, NULL); - RSA_get0_factors(k->rsa, NULL, &q); + ASSERT_PTR_NE(EVP_PKEY_get0_RSA(k->pkey), NULL); + RSA_get0_factors(EVP_PKEY_get0_RSA(k->pkey), NULL, &q); return q; } diff --git a/regress/unittests/sshkey/test_file.c b/regress/unittests/sshkey/test_file.c index 6b94cc1a90e..25f73de7961 100644 --- a/regress/unittests/sshkey/test_file.c +++ b/regress/unittests/sshkey/test_file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_file.c,v 1.11 2024/01/11 01:45:58 djm Exp $ */ +/* $OpenBSD: test_file.c,v 1.12 2024/08/15 00:52:23 djm Exp $ */ /* * Regress test for sshkey.h key management API * @@ -275,11 +275,12 @@ sshkey_file_tests(void) #ifndef OPENSSL_IS_BORINGSSL /* lacks EC_POINT_point2bn() */ a = load_bignum("ecdsa_1.param.priv"); b = load_bignum("ecdsa_1.param.pub"); - c = EC_POINT_point2bn(EC_KEY_get0_group(k1->ecdsa), - EC_KEY_get0_public_key(k1->ecdsa), POINT_CONVERSION_UNCOMPRESSED, - NULL, NULL); + c = EC_POINT_point2bn(EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(k1->pkey)), + EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(k1->pkey)), + POINT_CONVERSION_UNCOMPRESSED, NULL, NULL); ASSERT_PTR_NE(c, NULL); - ASSERT_BIGNUM_EQ(EC_KEY_get0_private_key(k1->ecdsa), a); + ASSERT_BIGNUM_EQ( + EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(k1->pkey)), a); ASSERT_BIGNUM_EQ(b, c); BN_free(a); BN_free(b); diff --git a/regress/unittests/sshkey/test_sshkey.c b/regress/unittests/sshkey/test_sshkey.c index c1cbb112823..5bf4b65cc05 100644 --- a/regress/unittests/sshkey/test_sshkey.c +++ b/regress/unittests/sshkey/test_sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: test_sshkey.c,v 1.24 2024/01/11 01:45:58 djm Exp $ */ +/* $OpenBSD: test_sshkey.c,v 1.25 2024/08/15 00:52:23 djm Exp $ */ /* * Regress test for sshkey.h key management API * @@ -204,7 +204,7 @@ sshkey_tests(void) TEST_START("new/free KEY_RSA"); k1 = sshkey_new(KEY_RSA); ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_NE(k1->rsa, NULL); + ASSERT_PTR_NE(k1->pkey, NULL); sshkey_free(k1); TEST_DONE(); @@ -221,7 +221,7 @@ sshkey_tests(void) TEST_START("new/free KEY_ECDSA"); k1 = sshkey_new(KEY_ECDSA); ASSERT_PTR_NE(k1, NULL); - ASSERT_PTR_EQ(k1->ecdsa, NULL); /* Can't allocate without NID */ + ASSERT_PTR_EQ(k1->pkey, NULL); /* Can't allocate without NID */ sshkey_free(k1); TEST_DONE(); #endif @@ -270,7 +270,7 @@ sshkey_tests(void) SSH_ERR_KEY_LENGTH); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); ASSERT_PTR_NE(kr, NULL); - ASSERT_PTR_NE(kr->rsa, NULL); + ASSERT_PTR_NE(EVP_PKEY_get0_RSA(kr->pkey), NULL); ASSERT_PTR_NE(rsa_n(kr), NULL); ASSERT_PTR_NE(rsa_e(kr), NULL); ASSERT_PTR_NE(rsa_p(kr), NULL); @@ -291,9 +291,11 @@ sshkey_tests(void) TEST_START("generate KEY_ECDSA"); ASSERT_INT_EQ(sshkey_generate(KEY_ECDSA, 256, &ke), 0); ASSERT_PTR_NE(ke, NULL); - ASSERT_PTR_NE(ke->ecdsa, NULL); - ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); - ASSERT_PTR_NE(EC_KEY_get0_private_key(ke->ecdsa), NULL); + ASSERT_PTR_NE(EVP_PKEY_get0_EC_KEY(ke->pkey), NULL); + ASSERT_PTR_NE(EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(ke->pkey)), + NULL); + ASSERT_PTR_NE(EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(ke->pkey)), + NULL); TEST_DONE(); #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ @@ -312,7 +314,7 @@ sshkey_tests(void) ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(kr, k1); ASSERT_INT_EQ(k1->type, KEY_RSA); - ASSERT_PTR_NE(k1->rsa, NULL); + ASSERT_PTR_NE(EVP_PKEY_get0_RSA(k1->pkey), NULL); ASSERT_PTR_NE(rsa_n(k1), NULL); ASSERT_PTR_NE(rsa_e(k1), NULL); ASSERT_PTR_EQ(rsa_p(k1), NULL); @@ -346,10 +348,12 @@ sshkey_tests(void) ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(ke, k1); ASSERT_INT_EQ(k1->type, KEY_ECDSA); - ASSERT_PTR_NE(k1->ecdsa, NULL); + ASSERT_PTR_NE(EVP_PKEY_get0_EC_KEY(k1->pkey), NULL); ASSERT_INT_EQ(k1->ecdsa_nid, ke->ecdsa_nid); - ASSERT_PTR_NE(EC_KEY_get0_public_key(ke->ecdsa), NULL); - ASSERT_PTR_EQ(EC_KEY_get0_private_key(k1->ecdsa), NULL); + ASSERT_PTR_NE(EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(ke->pkey)), + NULL); + ASSERT_PTR_EQ(EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(k1->pkey)), + NULL); TEST_DONE(); TEST_START("equal KEY_ECDSA/demoted KEY_ECDSA"); diff --git a/regress/unittests/test_helper/fuzz.c b/regress/unittests/test_helper/fuzz.c index 982e283efe7..fedb53294c2 100644 --- a/regress/unittests/test_helper/fuzz.c +++ b/regress/unittests/test_helper/fuzz.c @@ -214,7 +214,7 @@ siginfo(int unused __attribute__((__unused__))) struct fuzz * fuzz_begin(u_int strategies, const void *p, size_t l) { - struct fuzz *ret = calloc(sizeof(*ret), 1); + struct fuzz *ret = calloc(1, sizeof(*ret)); assert(p != NULL); assert(ret != NULL); diff --git a/sandbox-capsicum.c b/sandbox-capsicum.c index 11045251c88..9c329aa2ec6 100644 --- a/sandbox-capsicum.c +++ b/sandbox-capsicum.c @@ -45,8 +45,8 @@ */ struct ssh_sandbox { - struct monitor *monitor; - pid_t child_pid; + int m_recvfd; + int m_log_sendfd; }; struct ssh_sandbox * @@ -54,15 +54,10 @@ ssh_sandbox_init(struct monitor *monitor) { struct ssh_sandbox *box; - /* - * Strictly, we don't need to maintain any state here but we need - * to return non-NULL to satisfy the API. - */ debug3("%s: preparing capsicum sandbox", __func__); box = xcalloc(1, sizeof(*box)); - box->monitor = monitor; - box->child_pid = 0; - + box->m_recvfd = monitor->m_recvfd; + box->m_log_sendfd = monitor->m_log_sendfd; return box; } @@ -100,11 +95,11 @@ ssh_sandbox_child(struct ssh_sandbox *box) fatal("can't limit stderr: %m"); cap_rights_init(&rights, CAP_READ, CAP_WRITE); - if (cap_rights_limit(box->monitor->m_recvfd, &rights) < 0 && + if (cap_rights_limit(box->m_recvfd, &rights) < 0 && errno != ENOSYS) fatal("%s: failed to limit the network socket", __func__); cap_rights_init(&rights, CAP_WRITE); - if (cap_rights_limit(box->monitor->m_log_sendfd, &rights) < 0 && + if (cap_rights_limit(box->m_log_sendfd, &rights) < 0 && errno != ENOSYS) fatal("%s: failed to limit the logging socket", __func__); if (cap_enter() < 0 && errno != ENOSYS) @@ -112,17 +107,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3("%s: finished", __func__); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; -} - #endif /* SANDBOX_CAPSICUM */ diff --git a/sandbox-darwin.c b/sandbox-darwin.c index 59b4d286eea..08f4315b035 100644 --- a/sandbox-darwin.c +++ b/sandbox-darwin.c @@ -37,7 +37,7 @@ /* Darwin/OS X sandbox */ struct ssh_sandbox { - pid_t child_pid; + int junk; }; struct ssh_sandbox * @@ -51,8 +51,6 @@ ssh_sandbox_init(struct monitor *monitor) */ debug3("%s: preparing Darwin sandbox", __func__); box = xcalloc(1, sizeof(*box)); - box->child_pid = 0; - return box; } @@ -83,17 +81,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) __func__, strerror(errno)); } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3("%s: finished", __func__); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; -} - #endif /* SANDBOX_DARWIN */ diff --git a/sandbox-null.c b/sandbox-null.c index d4cb9188b61..6055eb86aa7 100644 --- a/sandbox-null.c +++ b/sandbox-null.c @@ -57,16 +57,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) /* Nothing to do here */ } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - /* Nothing to do here */ -} - #endif /* SANDBOX_NULL */ diff --git a/sandbox-pledge.c b/sandbox-pledge.c deleted file mode 100644 index 302f1cfedd3..00000000000 --- a/sandbox-pledge.c +++ /dev/null @@ -1,77 +0,0 @@ -/* $OpenBSD: sandbox-pledge.c,v 1.2 2020/10/18 11:32:01 djm Exp $ */ -/* - * Copyright (c) 2015 Theo de Raadt - * - * Permission to use, copy, modify, and 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. - */ - -#include "includes.h" - -#ifdef SANDBOX_PLEDGE - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "ssh-sandbox.h" -#include "xmalloc.h" - -struct ssh_sandbox { - pid_t child_pid; -}; - -struct ssh_sandbox * -ssh_sandbox_init(struct monitor *m) -{ - struct ssh_sandbox *box; - - debug3_f("preparing pledge sandbox"); - box = xcalloc(1, sizeof(*box)); - box->child_pid = 0; - - return box; -} - -void -ssh_sandbox_child(struct ssh_sandbox *box) -{ - if (pledge("stdio", NULL) == -1) - fatal_f("pledge()"); -} - -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3_f("finished"); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; - /* Nothing to do here */ -} - -#endif /* SANDBOX_PLEDGE */ diff --git a/sandbox-rlimit.c b/sandbox-rlimit.c index 26c61d26481..6bb4e56aa28 100644 --- a/sandbox-rlimit.c +++ b/sandbox-rlimit.c @@ -37,7 +37,7 @@ /* Minimal sandbox that sets zero nfiles, nprocs and filesize rlimits */ struct ssh_sandbox { - pid_t child_pid; + int junk; }; struct ssh_sandbox * @@ -51,8 +51,6 @@ ssh_sandbox_init(struct monitor *monitor) */ debug3_f("preparing rlimit sandbox"); box = xcalloc(1, sizeof(*box)); - box->child_pid = 0; - return box; } @@ -80,17 +78,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) #endif } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3_f("finished"); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; -} - #endif /* SANDBOX_RLIMIT */ diff --git a/sandbox-seccomp-filter.c b/sandbox-seccomp-filter.c index 23b40b64356..b31062c2b56 100644 --- a/sandbox-seccomp-filter.c +++ b/sandbox-seccomp-filter.c @@ -430,7 +430,7 @@ static const struct sock_fprog preauth_program = { }; struct ssh_sandbox { - pid_t child_pid; + int junk; }; struct ssh_sandbox * @@ -444,8 +444,6 @@ ssh_sandbox_init(struct monitor *monitor) */ debug3("%s: preparing seccomp filter sandbox", __func__); box = xcalloc(1, sizeof(*box)); - box->child_pid = 0; - return box; } @@ -527,17 +525,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) "PR_SET_NO_NEW_PRIVS failed", __func__); } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - free(box); - debug3("%s: finished", __func__); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - box->child_pid = child_pid; -} - #endif /* SANDBOX_SECCOMP_FILTER */ diff --git a/sandbox-solaris.c b/sandbox-solaris.c index 56ddb9a9942..0b88c71245c 100644 --- a/sandbox-solaris.c +++ b/sandbox-solaris.c @@ -97,18 +97,4 @@ ssh_sandbox_child(struct ssh_sandbox *box) fatal("setppriv: %s", strerror(errno)); } -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - priv_freeset(box->pset); - box->pset = NULL; - free(box); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - /* Nothing to do here */ -} - #endif /* SANDBOX_SOLARIS */ diff --git a/sandbox-systrace.c b/sandbox-systrace.c deleted file mode 100644 index e61d581aedb..00000000000 --- a/sandbox-systrace.c +++ /dev/null @@ -1,218 +0,0 @@ -/* $OpenBSD: sandbox-systrace.c,v 1.18 2015/10/02 01:39:26 deraadt Exp $ */ -/* - * Copyright (c) 2011 Damien Miller - * - * Permission to use, copy, modify, and 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. - */ - -#include "includes.h" - -#ifdef SANDBOX_SYSTRACE - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "atomicio.h" -#include "log.h" -#include "ssh-sandbox.h" -#include "xmalloc.h" - -struct sandbox_policy { - int syscall; - int action; -}; - -/* Permitted syscalls in preauth. Unlisted syscalls get SYSTR_POLICY_KILL */ -static const struct sandbox_policy preauth_policy[] = { - { SYS_exit, SYSTR_POLICY_PERMIT }, -#ifdef SYS_kbind - { SYS_kbind, SYSTR_POLICY_PERMIT }, -#endif - - { SYS_getpid, SYSTR_POLICY_PERMIT }, - { SYS_getpgid, SYSTR_POLICY_PERMIT }, - { SYS_clock_gettime, SYSTR_POLICY_PERMIT }, - { SYS_gettimeofday, SYSTR_POLICY_PERMIT }, - { SYS_nanosleep, SYSTR_POLICY_PERMIT }, - { SYS_sigprocmask, SYSTR_POLICY_PERMIT }, - -#ifdef SYS_getentropy - /* OpenBSD 5.6 and newer use getentropy(2) to seed arc4random(3). */ - { SYS_getentropy, SYSTR_POLICY_PERMIT }, -#else - /* Previous releases used sysctl(3)'s kern.arnd variable. */ - { SYS___sysctl, SYSTR_POLICY_PERMIT }, -#endif -#ifdef SYS_sendsyslog - { SYS_sendsyslog, SYSTR_POLICY_PERMIT }, -#endif - - { SYS_madvise, SYSTR_POLICY_PERMIT }, - { SYS_mmap, SYSTR_POLICY_PERMIT }, - { SYS_mprotect, SYSTR_POLICY_PERMIT }, - { SYS_mquery, SYSTR_POLICY_PERMIT }, - { SYS_munmap, SYSTR_POLICY_PERMIT }, - - { SYS_poll, SYSTR_POLICY_PERMIT }, - { SYS_select, SYSTR_POLICY_PERMIT }, - { SYS_read, SYSTR_POLICY_PERMIT }, - { SYS_write, SYSTR_POLICY_PERMIT }, - { SYS_shutdown, SYSTR_POLICY_PERMIT }, - { SYS_close, SYSTR_POLICY_PERMIT }, - - { SYS_open, SYSTR_POLICY_NEVER }, - - { -1, -1 } -}; - -struct ssh_sandbox { - int systrace_fd; - pid_t child_pid; - void (*osigchld)(int); -}; - -struct ssh_sandbox * -ssh_sandbox_init(struct monitor *monitor) -{ - struct ssh_sandbox *box; - - debug3("%s: preparing systrace sandbox", __func__); - box = xcalloc(1, sizeof(*box)); - box->systrace_fd = -1; - box->child_pid = 0; - box->osigchld = ssh_signal(SIGCHLD, SIG_IGN); - - return box; -} - -void -ssh_sandbox_child(struct ssh_sandbox *box) -{ - debug3("%s: ready", __func__); - ssh_signal(SIGCHLD, box->osigchld); - if (kill(getpid(), SIGSTOP) != 0) - fatal("%s: kill(%d, SIGSTOP)", __func__, getpid()); - debug3("%s: started", __func__); -} - -static void -ssh_sandbox_parent(struct ssh_sandbox *box, pid_t child_pid, - const struct sandbox_policy *allowed_syscalls) -{ - int dev_systrace, i, j, found, status; - pid_t pid; - struct systrace_policy policy; - - /* Wait for the child to send itself a SIGSTOP */ - debug3("%s: wait for child %ld", __func__, (long)child_pid); - do { - pid = waitpid(child_pid, &status, WUNTRACED); - } while (pid == -1 && errno == EINTR); - ssh_signal(SIGCHLD, box->osigchld); - if (!WIFSTOPPED(status)) { - if (WIFSIGNALED(status)) - fatal("%s: child terminated with signal %d", - __func__, WTERMSIG(status)); - if (WIFEXITED(status)) - fatal("%s: child exited with status %d", - __func__, WEXITSTATUS(status)); - fatal("%s: child not stopped", __func__); - } - debug3("%s: child %ld stopped", __func__, (long)child_pid); - box->child_pid = child_pid; - - /* Set up systracing of child */ - if ((dev_systrace = open("/dev/systrace", O_RDONLY)) == -1) - fatal("%s: open(\"/dev/systrace\"): %s", __func__, - strerror(errno)); - if (ioctl(dev_systrace, STRIOCCLONE, &box->systrace_fd) == -1) - fatal("%s: ioctl(STRIOCCLONE, %d): %s", __func__, - dev_systrace, strerror(errno)); - close(dev_systrace); - debug3("%s: systrace attach, fd=%d", __func__, box->systrace_fd); - if (ioctl(box->systrace_fd, STRIOCATTACH, &child_pid) == -1) - fatal("%s: ioctl(%d, STRIOCATTACH, %d): %s", __func__, - box->systrace_fd, child_pid, strerror(errno)); - - /* Allocate and assign policy */ - memset(&policy, 0, sizeof(policy)); - policy.strp_op = SYSTR_POLICY_NEW; - policy.strp_maxents = SYS_MAXSYSCALL; - if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) - fatal("%s: ioctl(%d, STRIOCPOLICY (new)): %s", __func__, - box->systrace_fd, strerror(errno)); - - policy.strp_op = SYSTR_POLICY_ASSIGN; - policy.strp_pid = box->child_pid; - if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) - fatal("%s: ioctl(%d, STRIOCPOLICY (assign)): %s", - __func__, box->systrace_fd, strerror(errno)); - - /* Set per-syscall policy */ - for (i = 0; i < SYS_MAXSYSCALL; i++) { - found = 0; - for (j = 0; allowed_syscalls[j].syscall != -1; j++) { - if (allowed_syscalls[j].syscall == i) { - found = 1; - break; - } - } - policy.strp_op = SYSTR_POLICY_MODIFY; - policy.strp_code = i; - policy.strp_policy = found ? - allowed_syscalls[j].action : SYSTR_POLICY_KILL; - if (found) - debug3("%s: policy: enable syscall %d", __func__, i); - if (ioctl(box->systrace_fd, STRIOCPOLICY, &policy) == -1) - fatal("%s: ioctl(%d, STRIOCPOLICY (modify)): %s", - __func__, box->systrace_fd, strerror(errno)); - } - - /* Signal the child to start running */ - debug3("%s: start child %ld", __func__, (long)child_pid); - if (kill(box->child_pid, SIGCONT) != 0) - fatal("%s: kill(%d, SIGCONT)", __func__, box->child_pid); -} - -void -ssh_sandbox_parent_finish(struct ssh_sandbox *box) -{ - /* Closing this before the child exits will terminate it */ - close(box->systrace_fd); - - free(box); - debug3("%s: finished", __func__); -} - -void -ssh_sandbox_parent_preauth(struct ssh_sandbox *box, pid_t child_pid) -{ - ssh_sandbox_parent(box, child_pid, preauth_policy); -} - -#endif /* SANDBOX_SYSTRACE */ diff --git a/scp.0 b/scp.0 index e098ddf55fc..aa16f2c5c07 100644 --- a/scp.0 +++ b/scp.0 @@ -91,67 +91,106 @@ DESCRIPTION the options listed below, and their possible values, see ssh_config(5). + AddKeysToAgent AddressFamily BatchMode BindAddress BindInterface + CASignatureAlgorithms CanonicalDomains CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs - CASignatureAlgorithms CertificateFile + ChannelTimeout CheckHostIP Ciphers + ClearAllForwardings Compression - ConnectionAttempts ConnectTimeout + ConnectionAttempts ControlMaster ControlPath ControlPersist - GlobalKnownHostsFile + DynamicForward + EnableEscapeCommandline + EnableSSHKeysign + EscapeChar + ExitOnForwardFailure + FingerprintHash + ForkAfterAuthentication + ForwardAgent + ForwardX11 + ForwardX11Timeout + ForwardX11Trusted GSSAPIAuthentication GSSAPIDelegateCredentials + GatewayPorts + GlobalKnownHostsFile HashKnownHosts Host - HostbasedAcceptedAlgorithms - HostbasedAuthentication HostKeyAlgorithms HostKeyAlias + HostbasedAcceptedAlgorithms + HostbasedAuthentication Hostname + IPQoS IdentitiesOnly IdentityAgent IdentityFile - IPQoS + IgnoreUnknown + Include KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms KnownHostsCommand + LocalCommand + LocalForward LogLevel + LogVerbose MACs NoHostAuthenticationForLocalhost NumberOfPasswordPrompts - PasswordAuthentication + ObscureKeystrokeTiming PKCS11Provider + PasswordAuthentication + PermitLocalCommand + PermitRemoteOpen Port PreferredAuthentications ProxyCommand ProxyJump + ProxyUseFdpass PubkeyAcceptedAlgorithms PubkeyAuthentication RekeyLimit + RemoteCommand + RemoteForward + RequestTTY RequiredRSASize + RevokedHostKeys + SecurityKeyProvider SendEnv - ServerAliveInterval ServerAliveCountMax + ServerAliveInterval + SessionType SetEnv + StdinNull + StreamLocalBindMask + StreamLocalBindUnlink StrictHostKeyChecking + SyslogFacility TCPKeepAlive + Tag + Tunnel + TunnelDevice UpdateHostKeys User UserKnownHostsFile VerifyHostKeyDNS + VisualHostKey + XAuthLocation -P port Specifies the port to connect to on the remote host. Note that @@ -229,4 +268,4 @@ CAVEATS requires careful quoting of any characters that have special meaning to the remote shell, such as quote characters. -OpenBSD 7.5 December 16, 2022 OpenBSD 7.5 +OpenBSD 7.6 December 6, 2024 OpenBSD 7.6 diff --git a/scp.1 b/scp.1 index 54c6fe3d5f3..aa2e2d8b53f 100644 --- a/scp.1 +++ b/scp.1 @@ -8,9 +8,9 @@ .\" .\" Created: Sun May 7 00:14:37 1995 ylo .\" -.\" $OpenBSD: scp.1,v 1.112 2022/12/16 07:13:22 djm Exp $ +.\" $OpenBSD: scp.1,v 1.113 2024/12/06 15:12:56 djm Exp $ .\" -.Dd $Mdocdate: December 16 2022 $ +.Dd $Mdocdate: December 6 2024 $ .Dt SCP 1 .Os .Sh NAME @@ -162,67 +162,106 @@ For full details of the options listed below, and their possible values, see .Xr ssh_config 5 . .Pp .Bl -tag -width Ds -offset indent -compact +.It AddKeysToAgent .It AddressFamily .It BatchMode .It BindAddress .It BindInterface +.It CASignatureAlgorithms .It CanonicalDomains .It CanonicalizeFallbackLocal .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs -.It CASignatureAlgorithms .It CertificateFile +.It ChannelTimeout .It CheckHostIP .It Ciphers +.It ClearAllForwardings .It Compression -.It ConnectionAttempts .It ConnectTimeout +.It ConnectionAttempts .It ControlMaster .It ControlPath .It ControlPersist -.It GlobalKnownHostsFile +.It DynamicForward +.It EnableEscapeCommandline +.It EnableSSHKeysign +.It EscapeChar +.It ExitOnForwardFailure +.It FingerprintHash +.It ForkAfterAuthentication +.It ForwardAgent +.It ForwardX11 +.It ForwardX11Timeout +.It ForwardX11Trusted .It GSSAPIAuthentication .It GSSAPIDelegateCredentials +.It GatewayPorts +.It GlobalKnownHostsFile .It HashKnownHosts .It Host -.It HostbasedAcceptedAlgorithms -.It HostbasedAuthentication .It HostKeyAlgorithms .It HostKeyAlias +.It HostbasedAcceptedAlgorithms +.It HostbasedAuthentication .It Hostname +.It IPQoS .It IdentitiesOnly .It IdentityAgent .It IdentityFile -.It IPQoS +.It IgnoreUnknown +.It Include .It KbdInteractiveAuthentication .It KbdInteractiveDevices .It KexAlgorithms .It KnownHostsCommand +.It LocalCommand +.It LocalForward .It LogLevel +.It LogVerbose .It MACs .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts -.It PasswordAuthentication +.It ObscureKeystrokeTiming .It PKCS11Provider +.It PasswordAuthentication +.It PermitLocalCommand +.It PermitRemoteOpen .It Port .It PreferredAuthentications .It ProxyCommand .It ProxyJump +.It ProxyUseFdpass .It PubkeyAcceptedAlgorithms .It PubkeyAuthentication .It RekeyLimit +.It RemoteCommand +.It RemoteForward +.It RequestTTY .It RequiredRSASize +.It RevokedHostKeys +.It SecurityKeyProvider .It SendEnv -.It ServerAliveInterval .It ServerAliveCountMax +.It ServerAliveInterval +.It SessionType .It SetEnv +.It StdinNull +.It StreamLocalBindMask +.It StreamLocalBindUnlink .It StrictHostKeyChecking +.It SyslogFacility .It TCPKeepAlive +.It Tag +.It Tunnel +.It TunnelDevice .It UpdateHostKeys .It User .It UserKnownHostsFile .It VerifyHostKeyDNS +.It VisualHostKey +.It XAuthLocation .El .It Fl P Ar port Specifies the port to connect to on the remote host. diff --git a/scp.c b/scp.c index ff0f9b27534..0ac05b92e80 100644 --- a/scp.c +++ b/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.261 2024/06/26 23:14:14 deraadt Exp $ */ +/* $OpenBSD: scp.c,v 1.263 2025/03/28 06:04:07 dtucker Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -685,6 +685,7 @@ main(int argc, char **argv) addargs(&args, "-oClearAllForwardings=yes"); addargs(&args, "-oRemoteCommand=none"); addargs(&args, "-oRequestTTY=no"); + addargs(&args, "-oControlMaster=no"); fflag = Tflag = tflag = 0; while ((ch = getopt(argc, argv, @@ -1276,7 +1277,7 @@ toremote(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) } if (host && throughlocal) { /* extended remote to remote */ if (mode == MODE_SFTP) { - if (remin == -1) { + if (remin == -1 || conn == NULL) { /* Connect to dest now */ conn = do_sftp_connect(thost, tuser, tport, sftp_direct, diff --git a/servconf.c b/servconf.c index adae64b4cdf..eeffe77ce36 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.411 2024/06/12 22:36:00 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.425 2025/02/25 06:25:30 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -72,6 +72,7 @@ #include "auth.h" #include "myproposal.h" #include "digest.h" +#include "version.h" #if !defined(SSHD_PAM_SERVICE) # define SSHD_PAM_SERVICE "sshd" @@ -182,6 +183,7 @@ initialize_server_options(ServerOptions *options) options->per_source_penalty.penalty_authfail = -1; options->per_source_penalty.penalty_noauth = -1; options->per_source_penalty.penalty_grace = -1; + options->per_source_penalty.penalty_refuseconnection = -1; options->per_source_penalty.penalty_max = -1; options->per_source_penalty.penalty_min = -1; options->max_authtries = -1; @@ -217,6 +219,8 @@ initialize_server_options(ServerOptions *options) options->num_channel_timeouts = 0; options->unused_connection_timeout = -1; options->sshd_session_path = NULL; + options->sshd_auth_path = NULL; + options->refuse_connection = -1; } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ @@ -440,11 +444,13 @@ fill_default_server_options(ServerOptions *options) if (options->per_source_penalty.penalty_crash == -1) options->per_source_penalty.penalty_crash = 90; if (options->per_source_penalty.penalty_grace == -1) - options->per_source_penalty.penalty_grace = 20; + options->per_source_penalty.penalty_grace = 10; if (options->per_source_penalty.penalty_authfail == -1) options->per_source_penalty.penalty_authfail = 5; if (options->per_source_penalty.penalty_noauth == -1) options->per_source_penalty.penalty_noauth = 1; + if (options->per_source_penalty.penalty_refuseconnection == -1) + options->per_source_penalty.penalty_refuseconnection = 10; if (options->per_source_penalty.penalty_min == -1) options->per_source_penalty.penalty_min = 15; if (options->per_source_penalty.penalty_max == -1) @@ -498,7 +504,15 @@ fill_default_server_options(ServerOptions *options) options->sshd_session_path = derelativise_path(_PATH_SSHD_SESSION); #else options->sshd_session_path = xstrdup(_PATH_SSHD_SESSION); -#endif /* WINDOWS */ +#endif // WINDOWS + if (options->sshd_auth_path == NULL) +#ifdef WINDOWS + options->sshd_auth_path = derelativise_path(_PATH_SSHD_AUTH); +#else + options->sshd_auth_path = xstrdup(_PATH_SSHD_AUTH); +#endif // WINDOWS + if (options->refuse_connection == -1) + options->refuse_connection = 0; assemble_algorithms(options); @@ -581,7 +595,7 @@ typedef enum { sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout, - sSshdSessionPath, + sSshdSessionPath, sSshdAuthPath, sRefuseConnection, sDeprecated, sIgnore, sUnsupported } ServerOpCodes; @@ -749,6 +763,8 @@ static struct { { "channeltimeout", sChannelTimeout, SSHCFG_ALL }, { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL }, { "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL }, + { "sshdauthpath", sSshdAuthPath, SSHCFG_GLOBAL }, + { "refuseconnection", sRefuseConnection, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; @@ -1033,46 +1049,82 @@ match_test_missing_fatal(const char *criteria, const char *attrib) * not match. */ static int -match_cfg_line(char **condition, int line, struct connection_info *ci) +match_cfg_line(const char *full_line, int *acp, char ***avp, + int line, struct connection_info *ci) { int result = 1, attributes = 0, port; - char *arg, *attrib, *cp = *condition; + char *arg, *attrib = NULL, *oattrib; - if (ci == NULL) - debug3("checking syntax for 'Match %s'", cp); - else - debug3("checking match for '%s' user %s host %s addr %s " - "laddr %s lport %d", cp, ci->user ? ci->user : "(null)", + if (ci == NULL) { + debug3("checking syntax for 'Match %s' on line %d", + full_line, line); + } else { + debug3("checking match for '%s' user %s%s host %s addr %s " + "laddr %s lport %d on line %d", full_line, + ci->user ? ci->user : "(null)", + ci->user_invalid ? " (invalid)" : "", ci->host ? ci->host : "(null)", ci->address ? ci->address : "(null)", - ci->laddress ? ci->laddress : "(null)", ci->lport); + ci->laddress ? ci->laddress : "(null)", ci->lport, line); + } - while ((attrib = strdelim(&cp)) && *attrib != '\0') { // CodeQL [SM02311]: false positive attrib is null checked + while ((oattrib = argv_next(acp, avp)) != NULL) { + attrib = xstrdup(oattrib); /* Terminate on comment */ if (*attrib == '#') { - cp = NULL; /* mark all arguments consumed */ + argv_consume(acp); /* mark all arguments consumed */ break; } arg = NULL; attributes++; /* Criterion "all" has no argument and must appear alone */ if (strcasecmp(attrib, "all") == 0) { - if (attributes > 1 || ((arg = strdelim(&cp)) != NULL && + if (attributes > 1 || + ((arg = argv_next(acp, avp)) != NULL && *arg != '\0' && *arg != '#')) { error("'all' cannot be combined with other " "Match attributes"); - return -1; + result = -1; + goto out; } if (arg != NULL && *arg == '#') - cp = NULL; /* mark all arguments consumed */ - *condition = cp; - return 1; + argv_consume(acp); /* consume remaining args */ + result = 1; + goto out; } + /* Criterion "invalid-user" also has no argument */ + if (strcasecmp(attrib, "invalid-user") == 0) { + if (ci == NULL) { + result = 0; + continue; + } + if (ci->user_invalid == 0) + result = 0; + else + debug("matched invalid-user at line %d", line); + continue; + } + + /* Keep this list in sync with below */ + if (strprefix(attrib, "user=", 1) != NULL || + strprefix(attrib, "group=", 1) != NULL || + strprefix(attrib, "host=", 1) != NULL || + strprefix(attrib, "address=", 1) != NULL || + strprefix(attrib, "localaddress=", 1) != NULL || + strprefix(attrib, "localport=", 1) != NULL || + strprefix(attrib, "rdomain=", 1) != NULL || + strprefix(attrib, "version=", 1) != NULL) { + arg = strchr(attrib, '='); + *(arg++) = '\0'; + } else { + arg = argv_next(acp, avp); + } + /* All other criteria require an argument */ - if ((arg = strdelim(&cp)) == NULL || - *arg == '\0' || *arg == '#') { + if (arg == NULL || *arg == '\0' || *arg == '#') { error("Missing Match criteria for %s", attrib); - return -1; + result = -1; + goto out; } if (strcasecmp(attrib, "user") == 0) { if (ci == NULL || (ci->test && ci->user == NULL)) { @@ -1096,7 +1148,8 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) match_test_missing_fatal("Group", "user"); switch (match_cfg_line_group(arg, line, ci->user)) { case -1: - return -1; + result = -1; + goto out; case 0: result = 0; } @@ -1132,7 +1185,8 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) result = 0; break; case -2: - return -1; + result = -1; + goto out; } } else if (strcasecmp(attrib, "localaddress") == 0){ if (ci == NULL || (ci->test && ci->laddress == NULL)) { @@ -1157,13 +1211,15 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) result = 0; break; case -2: - return -1; + result = -1; + goto out; } } else if (strcasecmp(attrib, "localport") == 0) { if ((port = a2port(arg)) == -1) { error("Invalid LocalPort '%s' on Match line", arg); - return -1; + result = -1; + goto out; } if (ci == NULL || (ci->test && ci->lport == -1)) { result = 0; @@ -1188,20 +1244,32 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) if (match_pattern_list(ci->rdomain, arg, 0) != 1) result = 0; else - debug("user %.100s matched 'RDomain %.100s' at " - "line %d", ci->rdomain, arg, line); + debug("connection RDomain %.100s matched " + "'RDomain %.100s' at line %d", + ci->rdomain, arg, line); + } else if (strcasecmp(attrib, "version") == 0) { + if (match_pattern_list(SSH_RELEASE, arg, 0) != 1) + result = 0; + else + debug("version %.100s matched " + "'version %.100s' at line %d", + SSH_RELEASE, arg, line); } else { - error("Unsupported Match attribute %s", attrib); - return -1; + error("Unsupported Match attribute %s", oattrib); + result = -1; + goto out; } + free(attrib); + attrib = NULL; } if (attributes == 0) { error("One or more attributes required for Match"); return -1; } - if (ci != NULL) - debug3("match %sfound", result ? "" : "not "); - *condition = cp; + out: + if (ci != NULL && result != -1) + debug3("match %sfound on line %d", result ? "" : "not ", line); + free(attrib); return result; } @@ -2013,6 +2081,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, xasprintf(&options->subsystem_args[options->num_subsystems], "%s%s%s", arg, *arg2 == '\0' ? "" : " ", arg2); free(arg2); + free(arg); argv_consume(&ac); options->num_subsystems++; break; @@ -2127,6 +2196,9 @@ process_server_config_line_depth(ServerOptions *options, char *line, } else if (strncmp(arg, "grace-exceeded:", 15) == 0) { p = arg + 15; intptr = &options->per_source_penalty.penalty_grace; + } else if (strncmp(arg, "refuseconnection:", 17) == 0) { + p = arg + 17; + intptr = &options->per_source_penalty.penalty_refuseconnection; } else if (strncmp(arg, "max:", 4) == 0) { p = arg + 4; intptr = &options->per_source_penalty.penalty_max; @@ -2412,7 +2484,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, if (cmdline) fatal("Match directive not supported as a command-line " "option"); - value = match_cfg_line(&str, linenum, + value = match_cfg_line(str, &ac, &av, linenum, (*inc_flags & SSHCFG_NEVERMATCH ? NULL : connectinfo)); if (value < 0) fatal("%s line %d: Bad Match condition", filename, @@ -2423,12 +2495,6 @@ process_server_config_line_depth(ServerOptions *options, char *line, * match block. */ *inc_flags &= ~SSHCFG_MATCH_ONLY; - /* - * If match_cfg_line() didn't consume all its arguments then - * arrange for the extra arguments check below to fail. - */ - if (str == NULL || *str == '\0') - argv_consume(&ac); break; case sPermitListen: @@ -2749,6 +2815,15 @@ process_server_config_line_depth(ServerOptions *options, char *line, charptr = &options->sshd_session_path; goto parse_filename; + case sSshdAuthPath: + charptr = &options->sshd_auth_path; + goto parse_filename; + + case sRefuseConnection: + intptr = &options->refuse_connection; + multistate_ptr = multistate_flag; + goto parse_multistate; + case sDeprecated: case sIgnore: case sUnsupported: @@ -2841,28 +2916,32 @@ parse_server_match_config(ServerOptions *options, copy_set_server_options(options, &mo, 0); } -int parse_server_match_testspec(struct connection_info *ci, char *spec) +int +parse_server_match_testspec(struct connection_info *ci, char *spec) { char *p; + const char *val; while ((p = strsep(&spec, ",")) && *p != '\0') { - if (strncmp(p, "addr=", 5) == 0) { - ci->address = xstrdup(p + 5); - } else if (strncmp(p, "host=", 5) == 0) { - ci->host = xstrdup(p + 5); - } else if (strncmp(p, "user=", 5) == 0) { - ci->user = xstrdup(p + 5); - } else if (strncmp(p, "laddr=", 6) == 0) { - ci->laddress = xstrdup(p + 6); - } else if (strncmp(p, "rdomain=", 8) == 0) { - ci->rdomain = xstrdup(p + 8); - } else if (strncmp(p, "lport=", 6) == 0) { - ci->lport = a2port(p + 6); + if ((val = strprefix(p, "addr=", 0)) != NULL) { + ci->address = xstrdup(val); + } else if ((val = strprefix(p, "host=", 0)) != NULL) { + ci->host = xstrdup(val); + } else if ((val = strprefix(p, "user=", 0)) != NULL) { + ci->user = xstrdup(val); + } else if ((val = strprefix(p, "laddr=", 0)) != NULL) { + ci->laddress = xstrdup(val); + } else if ((val = strprefix(p, "rdomain=", 0)) != NULL) { + ci->rdomain = xstrdup(val); + } else if ((val = strprefix(p, "lport=", 0)) != NULL) { + ci->lport = a2port(val); if (ci->lport == -1) { fprintf(stderr, "Invalid port '%s' in test mode" " specification %s\n", p+6, p); return -1; } + } else if (strcmp(p, "invalid-user") == 0) { + ci->user_invalid = 1; } else { fprintf(stderr, "Invalid test mode specification %s\n", p); @@ -2964,6 +3043,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(log_level); M_CP_INTOPT(required_rsa_size); M_CP_INTOPT(unused_connection_timeout); + M_CP_INTOPT(refuse_connection); /* * The bind_mask is a mode_t that may be unsigned, so we can't use @@ -3349,6 +3429,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink); dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info); + dump_cfg_fmtint(sRefuseConnection, o->refuse_connection); /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); @@ -3380,6 +3461,7 @@ dump_config(ServerOptions *o) dump_cfg_string(sRDomain, o->routing_domain); #endif dump_cfg_string(sSshdSessionPath, o->sshd_session_path); + dump_cfg_string(sSshdAuthPath, o->sshd_auth_path); dump_cfg_string(sPerSourcePenaltyExemptList, o->per_source_penalty_exempt); /* string arguments requiring a lookup */ @@ -3471,12 +3553,14 @@ dump_config(ServerOptions *o) if (o->per_source_penalty.enabled) { printf("persourcepenalties crash:%d authfail:%d noauth:%d " - "grace-exceeded:%d max:%d min:%d max-sources4:%d " - "max-sources6:%d overflow:%s overflow6:%s\n", + "grace-exceeded:%d refuseconnection:%d max:%d min:%d " + "max-sources4:%d max-sources6:%d " + "overflow:%s overflow6:%s\n", o->per_source_penalty.penalty_crash, o->per_source_penalty.penalty_authfail, o->per_source_penalty.penalty_noauth, o->per_source_penalty.penalty_grace, + o->per_source_penalty.penalty_refuseconnection, o->per_source_penalty.penalty_max, o->per_source_penalty.penalty_min, o->per_source_penalty.max_sources4, diff --git a/servconf.h b/servconf.h index 22b158d1057..9beb90fae3d 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.165 2024/06/12 22:36:00 djm Exp $ */ +/* $OpenBSD: servconf.h,v 1.168 2024/09/15 01:18:26 djm Exp $ */ /* * Author: Tatu Ylonen @@ -77,6 +77,7 @@ struct per_source_penalty { int penalty_grace; int penalty_authfail; int penalty_noauth; + int penalty_refuseconnection; int penalty_max; int penalty_min; }; @@ -248,11 +249,15 @@ typedef struct { int unused_connection_timeout; char *sshd_session_path; + char *sshd_auth_path; + + int refuse_connection; } ServerOptions; /* Information about the incoming connection as used by Match */ struct connection_info { const char *user; + int user_invalid; const char *host; /* possibly resolved hostname */ const char *address; /* remote address */ const char *laddress; /* local address */ diff --git a/serverloop.c b/serverloop.c index 757cc6f0244..40ddfb042b4 100644 --- a/serverloop.c +++ b/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.240 2024/06/17 08:28:31 djm Exp $ */ +/* $OpenBSD: serverloop.c,v 1.241 2024/11/26 22:01:37 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -690,7 +690,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) * For RSA keys, prefer to use the signature type negotiated * during KEX to the default (SHA1). */ - sigalg = NULL; + sigalg = sshkey_ssh_name(key); if (sshkey_type_plain(key->type) == KEY_RSA) { if (kex_rsa_sigalg != NULL) sigalg = kex_rsa_sigalg; @@ -699,6 +699,7 @@ server_input_hostkeys_prove(struct ssh *ssh, struct sshbuf **respp) else if (ssh->kex->flags & KEX_RSA_SHA2_256_SUPPORTED) sigalg = "rsa-sha2-256"; } + debug3_f("sign %s key (index %d) using sigalg %s", sshkey_type(key), ndx, sigalg == NULL ? "default" : sigalg); if ((r = sshbuf_put_cstring(sigbuf, diff --git a/session.c b/session.c index b9e03fff828..0308f5bd7d8 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.338 2024/05/17 00:30:24 djm Exp $ */ +/* $OpenBSD: session.c,v 1.341 2025/04/09 07:00:03 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -1448,7 +1448,7 @@ do_pwchange(Session *s) fprintf(stderr, "WARNING: Your password has expired.\n"); if (s->ttyfd != -1) { fprintf(stderr, - "You must change your password now and login again!\n"); + "You must change your password now and log in again!\n"); #ifdef WITH_SELINUX setexeccon(NULL); #endif @@ -1529,8 +1529,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); - /* remove hostkey from the child's memory */ - destroy_sensitive_data(); + /* remove keys from memory */ ssh_packet_clear_keys(ssh); /* Force a password change */ @@ -2165,10 +2164,6 @@ session_signal_req(struct ssh *ssh, Session *s) signame, s->forced ? "forced-command" : "subsystem"); goto out; } - if (mm_is_monitor()) { - error_f("session signalling requires privilege separation"); - goto out; - } debug_f("signal %s, killpg(%ld, %d)", signame, (long)s->pid, sig); temporarily_use_uid(s->pw); @@ -2196,7 +2191,8 @@ session_auth_agent_req(struct ssh *ssh, Session *s) if ((r = sshpkt_get_end(ssh)) != 0) sshpkt_fatal(ssh, r, "%s: parse packet", __func__); if (!auth_opts->permit_agent_forwarding_flag || - !options.allow_agent_forwarding) { + !options.allow_agent_forwarding || + options.disable_forwarding) { debug_f("agent forwarding disabled"); return 0; } @@ -2591,7 +2587,7 @@ session_setup_x11fwd(struct ssh *ssh, Session *s) ssh_packet_send_debug(ssh, "X11 forwarding disabled by key options."); return 0; } - if (!options.x11_forwarding) { + if (!options.x11_forwarding || options.disable_forwarding) { debug("X11 forwarding disabled in server configuration file."); return 0; } diff --git a/sftp-client.c b/sftp-client.c index 9ffcddff6b2..59507baa658 100644 --- a/sftp-client.c +++ b/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.176 2024/05/17 02:39:11 jsg Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.177 2025/03/11 07:48:51 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -2105,6 +2105,7 @@ sftp_upload(struct sftp_conn *conn, const char *local_path, close(local_fd); return -1; } + highwater = c.size; } openmode = SSH2_FXF_WRITE|SSH2_FXF_CREAT; diff --git a/sftp-server.0 b/sftp-server.0 index 23fdda39980..f86aaf12914 100644 --- a/sftp-server.0 +++ b/sftp-server.0 @@ -95,4 +95,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 7.5 July 27, 2021 OpenBSD 7.5 +OpenBSD 7.6 July 27, 2021 OpenBSD 7.6 diff --git a/sftp.0 b/sftp.0 index c6a9e60c40e..04fda74de4d 100644 --- a/sftp.0 +++ b/sftp.0 @@ -116,67 +116,106 @@ DESCRIPTION of the options listed below, and their possible values, see ssh_config(5). + AddKeysToAgent AddressFamily BatchMode BindAddress BindInterface + CASignatureAlgorithms CanonicalDomains CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs - CASignatureAlgorithms CertificateFile + ChannelTimeout CheckHostIP Ciphers + ClearAllForwardings Compression - ConnectionAttempts ConnectTimeout + ConnectionAttempts ControlMaster ControlPath ControlPersist - GlobalKnownHostsFile + DynamicForward + EnableEscapeCommandline + EnableSSHKeysign + EscapeChar + ExitOnForwardFailure + FingerprintHash + ForkAfterAuthentication + ForwardAgent + ForwardX11 + ForwardX11Timeout + ForwardX11Trusted GSSAPIAuthentication GSSAPIDelegateCredentials + GatewayPorts + GlobalKnownHostsFile HashKnownHosts Host - HostbasedAcceptedAlgorithms - HostbasedAuthentication HostKeyAlgorithms HostKeyAlias + HostbasedAcceptedAlgorithms + HostbasedAuthentication Hostname + IPQoS IdentitiesOnly IdentityAgent IdentityFile - IPQoS + IgnoreUnknown + Include KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms KnownHostsCommand + LocalCommand + LocalForward LogLevel + LogVerbose MACs NoHostAuthenticationForLocalhost NumberOfPasswordPrompts - PasswordAuthentication + ObscureKeystrokeTiming PKCS11Provider + PasswordAuthentication + PermitLocalCommand + PermitRemoteOpen Port PreferredAuthentications ProxyCommand ProxyJump + ProxyUseFdpass PubkeyAcceptedAlgorithms PubkeyAuthentication RekeyLimit + RemoteCommand + RemoteForward + RequestTTY RequiredRSASize + RevokedHostKeys + SecurityKeyProvider SendEnv - ServerAliveInterval ServerAliveCountMax + ServerAliveInterval + SessionType SetEnv + StdinNull + StreamLocalBindMask + StreamLocalBindUnlink StrictHostKeyChecking + SyslogFacility TCPKeepAlive + Tag + Tunnel + TunnelDevice UpdateHostKeys User UserKnownHostsFile VerifyHostKeyDNS + VisualHostKey + XAuthLocation -P port Specifies the port to connect to on the remote host. @@ -435,4 +474,4 @@ SEE ALSO T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- filexfer-00.txt, January 2001, work in progress material. -OpenBSD 7.5 December 16, 2022 OpenBSD 7.5 +OpenBSD 7.6 December 6, 2024 OpenBSD 7.6 diff --git a/sftp.1 b/sftp.1 index 68923ae20b1..651baaf85ed 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.143 2022/12/16 03:40:03 djm Exp $ +.\" $OpenBSD: sftp.1,v 1.144 2024/12/06 15:12:56 djm Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: December 16 2022 $ +.Dd $Mdocdate: December 6 2024 $ .Dt SFTP 1 .Os .Sh NAME @@ -224,67 +224,106 @@ For full details of the options listed below, and their possible values, see .Xr ssh_config 5 . .Pp .Bl -tag -width Ds -offset indent -compact +.It AddKeysToAgent .It AddressFamily .It BatchMode .It BindAddress .It BindInterface +.It CASignatureAlgorithms .It CanonicalDomains .It CanonicalizeFallbackLocal .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs -.It CASignatureAlgorithms .It CertificateFile +.It ChannelTimeout .It CheckHostIP .It Ciphers +.It ClearAllForwardings .It Compression -.It ConnectionAttempts .It ConnectTimeout +.It ConnectionAttempts .It ControlMaster .It ControlPath .It ControlPersist -.It GlobalKnownHostsFile +.It DynamicForward +.It EnableEscapeCommandline +.It EnableSSHKeysign +.It EscapeChar +.It ExitOnForwardFailure +.It FingerprintHash +.It ForkAfterAuthentication +.It ForwardAgent +.It ForwardX11 +.It ForwardX11Timeout +.It ForwardX11Trusted .It GSSAPIAuthentication .It GSSAPIDelegateCredentials +.It GatewayPorts +.It GlobalKnownHostsFile .It HashKnownHosts .It Host -.It HostbasedAcceptedAlgorithms -.It HostbasedAuthentication .It HostKeyAlgorithms .It HostKeyAlias +.It HostbasedAcceptedAlgorithms +.It HostbasedAuthentication .It Hostname +.It IPQoS .It IdentitiesOnly .It IdentityAgent .It IdentityFile -.It IPQoS +.It IgnoreUnknown +.It Include .It KbdInteractiveAuthentication .It KbdInteractiveDevices .It KexAlgorithms .It KnownHostsCommand +.It LocalCommand +.It LocalForward .It LogLevel +.It LogVerbose .It MACs .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts -.It PasswordAuthentication +.It ObscureKeystrokeTiming .It PKCS11Provider +.It PasswordAuthentication +.It PermitLocalCommand +.It PermitRemoteOpen .It Port .It PreferredAuthentications .It ProxyCommand .It ProxyJump +.It ProxyUseFdpass .It PubkeyAcceptedAlgorithms .It PubkeyAuthentication .It RekeyLimit +.It RemoteCommand +.It RemoteForward +.It RequestTTY .It RequiredRSASize +.It RevokedHostKeys +.It SecurityKeyProvider .It SendEnv -.It ServerAliveInterval .It ServerAliveCountMax +.It ServerAliveInterval +.It SessionType .It SetEnv +.It StdinNull +.It StreamLocalBindMask +.It StreamLocalBindUnlink .It StrictHostKeyChecking +.It SyslogFacility .It TCPKeepAlive +.It Tag +.It Tunnel +.It TunnelDevice .It UpdateHostKeys .It User .It UserKnownHostsFile .It VerifyHostKeyDNS +.It VisualHostKey +.It XAuthLocation .El .It Fl P Ar port Specifies the port to connect to on the remote host. diff --git a/sftp.c b/sftp.c index c968210ce0c..812a5da4bc4 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.239 2024/06/26 23:14:14 deraadt Exp $ */ +/* $OpenBSD: sftp.c,v 1.240 2025/03/28 06:04:07 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -2538,6 +2538,7 @@ main(int argc, char **argv) addargs(&args, "-oForwardX11 no"); addargs(&args, "-oPermitLocalCommand no"); addargs(&args, "-oClearAllForwardings yes"); + addargs(&args, "-oControlMaster no"); ll = SYSLOG_LEVEL_INFO; infile = stdin; diff --git a/sk-usbhid.c b/sk-usbhid.c index fe038f51e6a..3a75d4fe3ea 100644 --- a/sk-usbhid.c +++ b/sk-usbhid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sk-usbhid.c,v 1.46 2023/03/28 06:12:38 dtucker Exp $ */ +/* $OpenBSD: sk-usbhid.c,v 1.47 2024/12/03 08:31:49 djm Exp $ */ /* * Copyright (c) 2019 Markus Friedl * Copyright (c) 2020 Pedro Martelletto @@ -77,10 +77,11 @@ #define FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID 0 #endif +# include "misc.h" + #ifndef SK_STANDALONE # include "log.h" # include "xmalloc.h" -# include "misc.h" /* * If building as part of OpenSSH, then rename exported functions. * This must be done before including sk-api.h. @@ -990,13 +991,15 @@ sk_enroll(uint32_t alg, const uint8_t *challenge, size_t challenge_len, fido_strerr(r)); goto out; } - } else { + } else if (strcmp(fido_cred_fmt(cred), "none") != 0) { skdebug(__func__, "self-attested credential"); if ((r = fido_cred_verify_self(cred)) != FIDO_OK) { skdebug(__func__, "fido_cred_verify_self: %s", fido_strerr(r)); goto out; } + } else { + skdebug(__func__, "no attestation data"); } if ((response = calloc(1, sizeof(*response))) == NULL) { skdebug(__func__, "calloc response failed"); diff --git a/sntrup761.c b/sntrup761.c index 57368bd8061..123d01381c6 100644 --- a/sntrup761.c +++ b/sntrup761.c @@ -1,4 +1,5 @@ -/* $OpenBSD: sntrup761.c,v 1.6 2023/01/11 02:13:52 djm Exp $ */ + +/* $OpenBSD: sntrup761.c,v 1.8 2024/09/16 05:37:05 djm Exp $ */ /* * Public Domain, Authors: @@ -15,6 +16,8 @@ #include #include "crypto_api.h" +#define crypto_declassify(x, y) do {} while (0) + #define int8 crypto_int8 #define uint8 crypto_uint8 #define int16 crypto_int16 @@ -23,1251 +26,2134 @@ #define uint32 crypto_uint32 #define int64 crypto_int64 #define uint64 crypto_uint64 +extern volatile crypto_int16 crypto_int16_optblocker; +extern volatile crypto_int32 crypto_int32_optblocker; +extern volatile crypto_int64 crypto_int64_optblocker; -/* from supercop-20201130/crypto_sort/int32/portable4/int32_minmax.inc */ -#define int32_MINMAX(a,b) \ -do { \ - int64_t ab = (int64_t)b ^ (int64_t)a; \ - int64_t c = (int64_t)b - (int64_t)a; \ - c ^= ab & (c ^ b); \ - c >>= 31; \ - c &= ab; \ - a ^= c; \ - b ^= c; \ -} while(0) - -/* from supercop-20201130/crypto_sort/int32/portable4/sort.c */ - +/* from supercop-20240808/cryptoint/crypto_int16.h */ +/* auto-generated: cd cryptoint; ./autogen */ +/* cryptoint 20240806 */ -static void crypto_sort_int32(void *array,long long n) -{ - long long top,p,q,r,i,j; - int32 *x = array; +#ifndef crypto_int16_h +#define crypto_int16_h - if (n < 2) return; - top = 1; - while (top < n - top) top += top; +#define crypto_int16 int16_t +#define crypto_int16_unsigned uint16_t - for (p = top;p >= 1;p >>= 1) { - i = 0; - while (i + 2 * p <= n) { - for (j = i;j < i + p;++j) - int32_MINMAX(x[j],x[j+p]); - i += 2 * p; - } - for (j = i;j < n - p;++j) - int32_MINMAX(x[j],x[j+p]); - i = 0; - j = 0; - for (q = top;q > p;q >>= 1) { - if (j != i) for (;;) { - if (j == n - q) goto done; - int32 a = x[j + p]; - for (r = q;r > p;r >>= 1) - int32_MINMAX(a,x[j + r]); - x[j + p] = a; - ++j; - if (j == i + p) { - i += 2 * p; - break; - } - } - while (i + p <= n - q) { - for (j = i;j < i + p;++j) { - int32 a = x[j + p]; - for (r = q;r > p;r >>= 1) - int32_MINMAX(a,x[j+r]); - x[j + p] = a; - } - i += 2 * p; - } - /* now i + p > n - q */ - j = i; - while (j < n - q) { - int32 a = x[j + p]; - for (r = q;r > p;r >>= 1) - int32_MINMAX(a,x[j+r]); - x[j + p] = a; - ++j; - } - done: ; - } - } +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_load(const unsigned char *crypto_int16_s) { + crypto_int16 crypto_int16_z = 0; + crypto_int16_z |= ((crypto_int16) (*crypto_int16_s++)) << 0; + crypto_int16_z |= ((crypto_int16) (*crypto_int16_s++)) << 8; + return crypto_int16_z; } -/* from supercop-20201130/crypto_sort/uint32/useint32/sort.c */ - -/* can save time by vectorizing xor loops */ -/* can save time by integrating xor loops with int32_sort */ - -static void crypto_sort_uint32(void *array,long long n) -{ - crypto_uint32 *x = array; - long long j; - for (j = 0;j < n;++j) x[j] ^= 0x80000000; - crypto_sort_int32(array,n); - for (j = 0;j < n;++j) x[j] ^= 0x80000000; +__attribute__((unused)) +static inline +void crypto_int16_store(unsigned char *crypto_int16_s,crypto_int16 crypto_int16_x) { + *crypto_int16_s++ = crypto_int16_x >> 0; + *crypto_int16_s++ = crypto_int16_x >> 8; } -/* from supercop-20201130/crypto_kem/sntrup761/ref/uint32.c */ - -/* -CPU division instruction typically takes time depending on x. -This software is designed to take time independent of x. -Time still varies depending on m; user must ensure that m is constant. -Time also varies on CPUs where multiplication is variable-time. -There could be more CPU issues. -There could also be compiler issues. -*/ - -static void uint32_divmod_uint14(uint32 *q,uint16 *r,uint32 x,uint16 m) -{ - uint32 v = 0x80000000; - uint32 qpart; - uint32 mask; +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_negative_mask(crypto_int16 crypto_int16_x) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("sarw $15,%0" : "+r"(crypto_int16_x) : : "cc"); + return crypto_int16_x; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_y; + __asm__ ("sbfx %w0,%w1,15,1" : "=r"(crypto_int16_y) : "r"(crypto_int16_x) : ); + return crypto_int16_y; +#else + crypto_int16_x >>= 16-6; + crypto_int16_x ^= crypto_int16_optblocker; + crypto_int16_x >>= 5; + return crypto_int16_x; +#endif +} - v /= m; +__attribute__((unused)) +static inline +crypto_int16_unsigned crypto_int16_unsigned_topbit_01(crypto_int16_unsigned crypto_int16_x) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("shrw $15,%0" : "+r"(crypto_int16_x) : : "cc"); + return crypto_int16_x; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_y; + __asm__ ("ubfx %w0,%w1,15,1" : "=r"(crypto_int16_y) : "r"(crypto_int16_x) : ); + return crypto_int16_y; +#else + crypto_int16_x >>= 16-6; + crypto_int16_x ^= crypto_int16_optblocker; + crypto_int16_x >>= 5; + return crypto_int16_x; +#endif +} - /* caller guarantees m > 0 */ - /* caller guarantees m < 16384 */ - /* vm <= 2^31 <= vm+m-1 */ - /* xvm <= 2^31 x <= xvm+x(m-1) */ +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_negative_01(crypto_int16 crypto_int16_x) { + return crypto_int16_unsigned_topbit_01(crypto_int16_x); +} - *q = 0; +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_topbit_mask(crypto_int16 crypto_int16_x) { + return crypto_int16_negative_mask(crypto_int16_x); +} - qpart = (x*(uint64)v)>>31; - /* 2^31 qpart <= xv <= 2^31 qpart + 2^31-1 */ - /* 2^31 qpart m <= xvm <= 2^31 qpart m + (2^31-1)m */ - /* 2^31 qpart m <= 2^31 x <= 2^31 qpart m + (2^31-1)m + x(m-1) */ - /* 0 <= 2^31 newx <= (2^31-1)m + x(m-1) */ - /* 0 <= newx <= (1-1/2^31)m + x(m-1)/2^31 */ - /* 0 <= newx <= (1-1/2^31)(2^14-1) + (2^32-1)((2^14-1)-1)/2^31 */ +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_topbit_01(crypto_int16 crypto_int16_x) { + return crypto_int16_unsigned_topbit_01(crypto_int16_x); +} - x -= qpart*m; *q += qpart; - /* x <= 49146 */ +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_bottombit_mask(crypto_int16 crypto_int16_x) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("andw $1,%0" : "+r"(crypto_int16_x) : : "cc"); + return -crypto_int16_x; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_y; + __asm__ ("sbfx %w0,%w1,0,1" : "=r"(crypto_int16_y) : "r"(crypto_int16_x) : ); + return crypto_int16_y; +#else + crypto_int16_x &= 1 ^ crypto_int16_optblocker; + return -crypto_int16_x; +#endif +} - qpart = (x*(uint64)v)>>31; - /* 0 <= newx <= (1-1/2^31)m + x(m-1)/2^31 */ - /* 0 <= newx <= m + 49146(2^14-1)/2^31 */ - /* 0 <= newx <= m + 0.4 */ - /* 0 <= newx <= m */ +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_bottombit_01(crypto_int16 crypto_int16_x) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("andw $1,%0" : "+r"(crypto_int16_x) : : "cc"); + return crypto_int16_x; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_y; + __asm__ ("ubfx %w0,%w1,0,1" : "=r"(crypto_int16_y) : "r"(crypto_int16_x) : ); + return crypto_int16_y; +#else + crypto_int16_x &= 1 ^ crypto_int16_optblocker; + return crypto_int16_x; +#endif +} - x -= qpart*m; *q += qpart; - /* x <= m */ +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_bitinrangepublicpos_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_s) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("sarw %%cl,%0" : "+r"(crypto_int16_x) : "c"(crypto_int16_s) : "cc"); +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("sxth %w0,%w0\n asr %w0,%w0,%w1" : "+&r"(crypto_int16_x) : "r"(crypto_int16_s) : ); +#else + crypto_int16_x >>= crypto_int16_s ^ crypto_int16_optblocker; +#endif + return crypto_int16_bottombit_mask(crypto_int16_x); +} - x -= m; *q += 1; - mask = -(x>>31); - x += mask&(uint32)m; *q += mask; - /* x < m */ +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_bitinrangepublicpos_01(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_s) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("sarw %%cl,%0" : "+r"(crypto_int16_x) : "c"(crypto_int16_s) : "cc"); +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("sxth %w0,%w0\n asr %w0,%w0,%w1" : "+&r"(crypto_int16_x) : "r"(crypto_int16_s) : ); +#else + crypto_int16_x >>= crypto_int16_s ^ crypto_int16_optblocker; +#endif + return crypto_int16_bottombit_01(crypto_int16_x); +} - *r = x; +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_shlmod(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_s) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16_s &= 15; + __asm__ ("shlw %%cl,%0" : "+r"(crypto_int16_x) : "c"(crypto_int16_s) : "cc"); +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("and %w0,%w0,15\n and %w1,%w1,65535\n lsl %w1,%w1,%w0" : "+&r"(crypto_int16_s), "+r"(crypto_int16_x) : : ); +#else + int crypto_int16_k, crypto_int16_l; + for (crypto_int16_l = 0,crypto_int16_k = 1;crypto_int16_k < 16;++crypto_int16_l,crypto_int16_k *= 2) + crypto_int16_x ^= (crypto_int16_x ^ (crypto_int16_x << crypto_int16_k)) & crypto_int16_bitinrangepublicpos_mask(crypto_int16_s,crypto_int16_l); +#endif + return crypto_int16_x; } +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_shrmod(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_s) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16_s &= 15; + __asm__ ("sarw %%cl,%0" : "+r"(crypto_int16_x) : "c"(crypto_int16_s) : "cc"); +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("and %w0,%w0,15\n sxth %w1,%w1\n asr %w1,%w1,%w0" : "+&r"(crypto_int16_s), "+r"(crypto_int16_x) : : ); +#else + int crypto_int16_k, crypto_int16_l; + for (crypto_int16_l = 0,crypto_int16_k = 1;crypto_int16_k < 16;++crypto_int16_l,crypto_int16_k *= 2) + crypto_int16_x ^= (crypto_int16_x ^ (crypto_int16_x >> crypto_int16_k)) & crypto_int16_bitinrangepublicpos_mask(crypto_int16_s,crypto_int16_l); +#endif + return crypto_int16_x; +} + +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_bitmod_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_s) { + crypto_int16_x = crypto_int16_shrmod(crypto_int16_x,crypto_int16_s); + return crypto_int16_bottombit_mask(crypto_int16_x); +} + +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_bitmod_01(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_s) { + crypto_int16_x = crypto_int16_shrmod(crypto_int16_x,crypto_int16_s); + return crypto_int16_bottombit_01(crypto_int16_x); +} + +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_nonzero_mask(crypto_int16 crypto_int16_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $-1,%1\n testw %2,%2\n cmovnew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("tst %w1,65535\n csetm %w0,ne" : "=r"(crypto_int16_z) : "r"(crypto_int16_x) : "cc"); + return crypto_int16_z; +#else + crypto_int16_x |= -crypto_int16_x; + return crypto_int16_negative_mask(crypto_int16_x); +#endif +} -static uint16 uint32_mod_uint14(uint32 x,uint16 m) -{ - uint32 q; - uint16 r; - uint32_divmod_uint14(&q,&r,x,m); - return r; +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_nonzero_01(crypto_int16 crypto_int16_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $1,%1\n testw %2,%2\n cmovnew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("tst %w1,65535\n cset %w0,ne" : "=r"(crypto_int16_z) : "r"(crypto_int16_x) : "cc"); + return crypto_int16_z; +#else + crypto_int16_x |= -crypto_int16_x; + return crypto_int16_unsigned_topbit_01(crypto_int16_x); +#endif } -/* from supercop-20201130/crypto_kem/sntrup761/ref/int32.c */ +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_positive_mask(crypto_int16 crypto_int16_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $-1,%1\n testw %2,%2\n cmovgw %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("sxth %w0,%w1\n cmp %w0,0\n csetm %w0,gt" : "=r"(crypto_int16_z) : "r"(crypto_int16_x) : "cc"); + return crypto_int16_z; +#else + crypto_int16 crypto_int16_z = -crypto_int16_x; + crypto_int16_z ^= crypto_int16_x & crypto_int16_z; + return crypto_int16_negative_mask(crypto_int16_z); +#endif +} -static void int32_divmod_uint14(int32 *q,uint16 *r,int32 x,uint16 m) -{ - uint32 uq,uq2; - uint16 ur,ur2; - uint32 mask; +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_positive_01(crypto_int16 crypto_int16_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $1,%1\n testw %2,%2\n cmovgw %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("sxth %w0,%w1\n cmp %w0,0\n cset %w0,gt" : "=r"(crypto_int16_z) : "r"(crypto_int16_x) : "cc"); + return crypto_int16_z; +#else + crypto_int16 crypto_int16_z = -crypto_int16_x; + crypto_int16_z ^= crypto_int16_x & crypto_int16_z; + return crypto_int16_unsigned_topbit_01(crypto_int16_z); +#endif +} - uint32_divmod_uint14(&uq,&ur,0x80000000+(uint32)x,m); - uint32_divmod_uint14(&uq2,&ur2,0x80000000,m); - ur -= ur2; uq -= uq2; - mask = -(uint32)(ur>>15); - ur += mask&m; uq += mask; - *r = ur; *q = uq; +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_zero_mask(crypto_int16 crypto_int16_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $-1,%1\n testw %2,%2\n cmovew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("tst %w1,65535\n csetm %w0,eq" : "=r"(crypto_int16_z) : "r"(crypto_int16_x) : "cc"); + return crypto_int16_z; +#else + return ~crypto_int16_nonzero_mask(crypto_int16_x); +#endif } +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_zero_01(crypto_int16 crypto_int16_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $1,%1\n testw %2,%2\n cmovew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("tst %w1,65535\n cset %w0,eq" : "=r"(crypto_int16_z) : "r"(crypto_int16_x) : "cc"); + return crypto_int16_z; +#else + return 1-crypto_int16_nonzero_01(crypto_int16_x); +#endif +} -static uint16 int32_mod_uint14(int32 x,uint16 m) -{ - int32 q; - uint16 r; - int32_divmod_uint14(&q,&r,x,m); - return r; +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_unequal_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $-1,%1\n cmpw %3,%2\n cmovnew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("and %w0,%w1,65535\n cmp %w0,%w2,uxth\n csetm %w0,ne" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; +#else + return crypto_int16_nonzero_mask(crypto_int16_x ^ crypto_int16_y); +#endif } -/* from supercop-20201130/crypto_kem/sntrup761/ref/paramsmenu.h */ -/* pick one of these three: */ -#define SIZE761 -#undef SIZE653 -#undef SIZE857 +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_unequal_01(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $1,%1\n cmpw %3,%2\n cmovnew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("and %w0,%w1,65535\n cmp %w0,%w2,uxth\n cset %w0,ne" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; +#else + return crypto_int16_nonzero_01(crypto_int16_x ^ crypto_int16_y); +#endif +} -/* pick one of these two: */ -#define SNTRUP /* Streamlined NTRU Prime */ -#undef LPR /* NTRU LPRime */ +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_equal_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $-1,%1\n cmpw %3,%2\n cmovew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("and %w0,%w1,65535\n cmp %w0,%w2,uxth\n csetm %w0,eq" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; +#else + return ~crypto_int16_unequal_mask(crypto_int16_x,crypto_int16_y); +#endif +} -/* from supercop-20201130/crypto_kem/sntrup761/ref/params.h */ -#ifndef params_H -#define params_H +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_equal_01(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $1,%1\n cmpw %3,%2\n cmovew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("and %w0,%w1,65535\n cmp %w0,%w2,uxth\n cset %w0,eq" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; +#else + return 1-crypto_int16_unequal_01(crypto_int16_x,crypto_int16_y); +#endif +} -/* menu of parameter choices: */ +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_min(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("cmpw %1,%0\n cmovgw %1,%0" : "+r"(crypto_int16_x) : "r"(crypto_int16_y) : "cc"); + return crypto_int16_x; +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("sxth %w0,%w0\n cmp %w0,%w1,sxth\n csel %w0,%w0,%w1,lt" : "+&r"(crypto_int16_x) : "r"(crypto_int16_y) : "cc"); + return crypto_int16_x; +#else + crypto_int16 crypto_int16_r = crypto_int16_y ^ crypto_int16_x; + crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; + crypto_int16_z ^= crypto_int16_r & (crypto_int16_z ^ crypto_int16_y); + crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); + crypto_int16_z &= crypto_int16_r; + return crypto_int16_x ^ crypto_int16_z; +#endif +} +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_max(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("cmpw %1,%0\n cmovlw %1,%0" : "+r"(crypto_int16_x) : "r"(crypto_int16_y) : "cc"); + return crypto_int16_x; +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("sxth %w0,%w0\n cmp %w0,%w1,sxth\n csel %w0,%w1,%w0,lt" : "+&r"(crypto_int16_x) : "r"(crypto_int16_y) : "cc"); + return crypto_int16_x; +#else + crypto_int16 crypto_int16_r = crypto_int16_y ^ crypto_int16_x; + crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; + crypto_int16_z ^= crypto_int16_r & (crypto_int16_z ^ crypto_int16_y); + crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); + crypto_int16_z &= crypto_int16_r; + return crypto_int16_y ^ crypto_int16_z; +#endif +} -/* what the menu means: */ +__attribute__((unused)) +static inline +void crypto_int16_minmax(crypto_int16 *crypto_int16_p,crypto_int16 *crypto_int16_q) { + crypto_int16 crypto_int16_x = *crypto_int16_p; + crypto_int16 crypto_int16_y = *crypto_int16_q; +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_z; + __asm__ ("cmpw %2,%1\n movw %1,%0\n cmovgw %2,%1\n cmovgw %0,%2" : "=&r"(crypto_int16_z), "+&r"(crypto_int16_x), "+r"(crypto_int16_y) : : "cc"); + *crypto_int16_p = crypto_int16_x; + *crypto_int16_q = crypto_int16_y; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_r, crypto_int16_s; + __asm__ ("sxth %w0,%w0\n cmp %w0,%w3,sxth\n csel %w1,%w0,%w3,lt\n csel %w2,%w3,%w0,lt" : "+&r"(crypto_int16_x), "=&r"(crypto_int16_r), "=r"(crypto_int16_s) : "r"(crypto_int16_y) : "cc"); + *crypto_int16_p = crypto_int16_r; + *crypto_int16_q = crypto_int16_s; +#else + crypto_int16 crypto_int16_r = crypto_int16_y ^ crypto_int16_x; + crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; + crypto_int16_z ^= crypto_int16_r & (crypto_int16_z ^ crypto_int16_y); + crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); + crypto_int16_z &= crypto_int16_r; + crypto_int16_x ^= crypto_int16_z; + crypto_int16_y ^= crypto_int16_z; + *crypto_int16_p = crypto_int16_x; + *crypto_int16_q = crypto_int16_y; +#endif +} -#if defined(SIZE761) -#define p 761 -#define q 4591 -#define Rounded_bytes 1007 -#ifndef LPR -#define Rq_bytes 1158 -#define w 286 +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_smaller_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $-1,%1\n cmpw %3,%2\n cmovlw %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("sxth %w0,%w1\n cmp %w0,%w2,sxth\n csetm %w0,lt" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; #else -#define w 250 -#define tau0 2156 -#define tau1 114 -#define tau2 2007 -#define tau3 287 + crypto_int16 crypto_int16_r = crypto_int16_x ^ crypto_int16_y; + crypto_int16 crypto_int16_z = crypto_int16_x - crypto_int16_y; + crypto_int16_z ^= crypto_int16_r & (crypto_int16_z ^ crypto_int16_x); + return crypto_int16_negative_mask(crypto_int16_z); #endif +} -#elif defined(SIZE653) -#define p 653 -#define q 4621 -#define Rounded_bytes 865 -#ifndef LPR -#define Rq_bytes 994 -#define w 288 +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_smaller_01(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $1,%1\n cmpw %3,%2\n cmovlw %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("sxth %w0,%w1\n cmp %w0,%w2,sxth\n cset %w0,lt" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; #else -#define w 252 -#define tau0 2175 -#define tau1 113 -#define tau2 2031 -#define tau3 290 + crypto_int16 crypto_int16_r = crypto_int16_x ^ crypto_int16_y; + crypto_int16 crypto_int16_z = crypto_int16_x - crypto_int16_y; + crypto_int16_z ^= crypto_int16_r & (crypto_int16_z ^ crypto_int16_x); + return crypto_int16_unsigned_topbit_01(crypto_int16_z); #endif +} -#elif defined(SIZE857) -#define p 857 -#define q 5167 -#define Rounded_bytes 1152 -#ifndef LPR -#define Rq_bytes 1322 -#define w 322 +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_leq_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $-1,%1\n cmpw %3,%2\n cmovlew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("sxth %w0,%w1\n cmp %w0,%w2,sxth\n csetm %w0,le" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; #else -#define w 281 -#define tau0 2433 -#define tau1 101 -#define tau2 2265 -#define tau3 324 + return ~crypto_int16_smaller_mask(crypto_int16_y,crypto_int16_x); #endif +} +__attribute__((unused)) +static inline +crypto_int16 crypto_int16_leq_01(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 crypto_int16_q,crypto_int16_z; + __asm__ ("xorw %0,%0\n movw $1,%1\n cmpw %3,%2\n cmovlew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int16 crypto_int16_z; + __asm__ ("sxth %w0,%w1\n cmp %w0,%w2,sxth\n cset %w0,le" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); + return crypto_int16_z; #else -#error "no parameter set defined" + return 1-crypto_int16_smaller_01(crypto_int16_y,crypto_int16_x); #endif +} -#ifdef LPR -#define I 256 +__attribute__((unused)) +static inline +int crypto_int16_ones_num(crypto_int16 crypto_int16_x) { + crypto_int16_unsigned crypto_int16_y = crypto_int16_x; + const crypto_int16 C0 = 0x5555; + const crypto_int16 C1 = 0x3333; + const crypto_int16 C2 = 0x0f0f; + crypto_int16_y -= ((crypto_int16_y >> 1) & C0); + crypto_int16_y = (crypto_int16_y & C1) + ((crypto_int16_y >> 2) & C1); + crypto_int16_y = (crypto_int16_y + (crypto_int16_y >> 4)) & C2; + crypto_int16_y = (crypto_int16_y + (crypto_int16_y >> 8)) & 0xff; + return crypto_int16_y; +} + +__attribute__((unused)) +static inline +int crypto_int16_bottomzeros_num(crypto_int16 crypto_int16_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int16 fallback = 16; + __asm__ ("bsfw %0,%0\n cmovew %1,%0" : "+&r"(crypto_int16_x) : "r"(fallback) : "cc"); + return crypto_int16_x; +#elif defined(__GNUC__) && defined(__aarch64__) + int64_t crypto_int16_y; + __asm__ ("orr %w0,%w1,-65536\n rbit %w0,%w0\n clz %w0,%w0" : "=r"(crypto_int16_y) : "r"(crypto_int16_x) : ); + return crypto_int16_y; +#else + crypto_int16 crypto_int16_y = crypto_int16_x ^ (crypto_int16_x-1); + crypto_int16_y = ((crypto_int16) crypto_int16_y) >> 1; + crypto_int16_y &= ~(crypto_int16_x & (((crypto_int16) 1) << (16-1))); + return crypto_int16_ones_num(crypto_int16_y); #endif +} #endif -/* from supercop-20201130/crypto_kem/sntrup761/ref/Decode.h */ -#ifndef Decode_H -#define Decode_H +/* from supercop-20240808/cryptoint/crypto_int32.h */ +/* auto-generated: cd cryptoint; ./autogen */ +/* cryptoint 20240806 */ +#ifndef crypto_int32_h +#define crypto_int32_h -/* Decode(R,s,M,len) */ -/* assumes 0 < M[i] < 16384 */ -/* produces 0 <= R[i] < M[i] */ +#define crypto_int32 int32_t +#define crypto_int32_unsigned uint32_t -#endif -/* from supercop-20201130/crypto_kem/sntrup761/ref/Decode.c */ -static void Decode(uint16 *out,const unsigned char *S,const uint16 *M,long long len) -{ - if (len == 1) { - if (M[0] == 1) - *out = 0; - else if (M[0] <= 256) - *out = uint32_mod_uint14(S[0],M[0]); - else - *out = uint32_mod_uint14(S[0]+(((uint16)S[1])<<8),M[0]); - } - if (len > 1) { - uint16 R2[(len+1)/2]; - uint16 M2[(len+1)/2]; - uint16 bottomr[len/2]; - uint32 bottomt[len/2]; - long long i; - for (i = 0;i < len-1;i += 2) { - uint32 m = M[i]*(uint32) M[i+1]; - if (m > 256*16383) { - bottomt[i/2] = 256*256; - bottomr[i/2] = S[0]+256*S[1]; - S += 2; - M2[i/2] = (((m+255)>>8)+255)>>8; - } else if (m >= 16384) { - bottomt[i/2] = 256; - bottomr[i/2] = S[0]; - S += 1; - M2[i/2] = (m+255)>>8; - } else { - bottomt[i/2] = 1; - bottomr[i/2] = 0; - M2[i/2] = m; - } - } - if (i < len) - M2[i/2] = M[i]; - Decode(R2,S,M2,(len+1)/2); - for (i = 0;i < len-1;i += 2) { - uint32 r = bottomr[i/2]; - uint32 r1; - uint16 r0; - r += bottomt[i/2]*R2[i/2]; - uint32_divmod_uint14(&r1,&r0,r,M[i]); - r1 = uint32_mod_uint14(r1,M[i+1]); /* only needed for invalid inputs */ - *out++ = r0; - *out++ = r1; - } - if (i < len) - *out++ = R2[i/2]; - } +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_load(const unsigned char *crypto_int32_s) { + crypto_int32 crypto_int32_z = 0; + crypto_int32_z |= ((crypto_int32) (*crypto_int32_s++)) << 0; + crypto_int32_z |= ((crypto_int32) (*crypto_int32_s++)) << 8; + crypto_int32_z |= ((crypto_int32) (*crypto_int32_s++)) << 16; + crypto_int32_z |= ((crypto_int32) (*crypto_int32_s++)) << 24; + return crypto_int32_z; } -/* from supercop-20201130/crypto_kem/sntrup761/ref/Encode.h */ -#ifndef Encode_H -#define Encode_H - - -/* Encode(s,R,M,len) */ -/* assumes 0 <= R[i] < M[i] < 16384 */ +__attribute__((unused)) +static inline +void crypto_int32_store(unsigned char *crypto_int32_s,crypto_int32 crypto_int32_x) { + *crypto_int32_s++ = crypto_int32_x >> 0; + *crypto_int32_s++ = crypto_int32_x >> 8; + *crypto_int32_s++ = crypto_int32_x >> 16; + *crypto_int32_s++ = crypto_int32_x >> 24; +} +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_negative_mask(crypto_int32 crypto_int32_x) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("sarl $31,%0" : "+r"(crypto_int32_x) : : "cc"); + return crypto_int32_x; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_y; + __asm__ ("asr %w0,%w1,31" : "=r"(crypto_int32_y) : "r"(crypto_int32_x) : ); + return crypto_int32_y; +#else + crypto_int32_x >>= 32-6; + crypto_int32_x ^= crypto_int32_optblocker; + crypto_int32_x >>= 5; + return crypto_int32_x; #endif - -/* from supercop-20201130/crypto_kem/sntrup761/ref/Encode.c */ - -/* 0 <= R[i] < M[i] < 16384 */ -static void Encode(unsigned char *out,const uint16 *R,const uint16 *M,long long len) -{ - if (len == 1) { - uint16 r = R[0]; - uint16 m = M[0]; - while (m > 1) { - *out++ = r; - r >>= 8; - m = (m+255)>>8; - } - } - if (len > 1) { - uint16 R2[(len+1)/2]; - uint16 M2[(len+1)/2]; - long long i; - for (i = 0;i < len-1;i += 2) { - uint32 m0 = M[i]; - uint32 r = R[i]+R[i+1]*m0; - uint32 m = M[i+1]*m0; - while (m >= 16384) { - *out++ = r; - r >>= 8; - m = (m+255)>>8; - } - R2[i/2] = r; - M2[i/2] = m; - } - if (i < len) { - R2[i/2] = R[i]; - M2[i/2] = M[i]; - } - Encode(out,R2,M2,(len+1)/2); - } } -/* from supercop-20201130/crypto_kem/sntrup761/ref/kem.c */ - -#ifdef LPR +__attribute__((unused)) +static inline +crypto_int32_unsigned crypto_int32_unsigned_topbit_01(crypto_int32_unsigned crypto_int32_x) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("shrl $31,%0" : "+r"(crypto_int32_x) : : "cc"); + return crypto_int32_x; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_y; + __asm__ ("lsr %w0,%w1,31" : "=r"(crypto_int32_y) : "r"(crypto_int32_x) : ); + return crypto_int32_y; +#else + crypto_int32_x >>= 32-6; + crypto_int32_x ^= crypto_int32_optblocker; + crypto_int32_x >>= 5; + return crypto_int32_x; #endif +} +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_negative_01(crypto_int32 crypto_int32_x) { + return crypto_int32_unsigned_topbit_01(crypto_int32_x); +} -/* ----- masks */ - -#ifndef LPR +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_topbit_mask(crypto_int32 crypto_int32_x) { + return crypto_int32_negative_mask(crypto_int32_x); +} -/* return -1 if x!=0; else return 0 */ -static int int16_nonzero_mask(int16 x) -{ - uint16 u = x; /* 0, else 1...65535 */ - uint32 v = u; /* 0, else 1...65535 */ - v = -v; /* 0, else 2^32-65535...2^32-1 */ - v >>= 31; /* 0, else 1 */ - return -v; /* 0, else -1 */ +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_topbit_01(crypto_int32 crypto_int32_x) { + return crypto_int32_unsigned_topbit_01(crypto_int32_x); } +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_bottombit_mask(crypto_int32 crypto_int32_x) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("andl $1,%0" : "+r"(crypto_int32_x) : : "cc"); + return -crypto_int32_x; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_y; + __asm__ ("sbfx %w0,%w1,0,1" : "=r"(crypto_int32_y) : "r"(crypto_int32_x) : ); + return crypto_int32_y; +#else + crypto_int32_x &= 1 ^ crypto_int32_optblocker; + return -crypto_int32_x; #endif - -/* return -1 if x<0; otherwise return 0 */ -static int int16_negative_mask(int16 x) -{ - uint16 u = x; - u >>= 15; - return -(int) u; - /* alternative with gcc -fwrapv: */ - /* x>>15 compiles to CPU's arithmetic right shift */ } -/* ----- arithmetic mod 3 */ +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_bottombit_01(crypto_int32 crypto_int32_x) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("andl $1,%0" : "+r"(crypto_int32_x) : : "cc"); + return crypto_int32_x; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_y; + __asm__ ("ubfx %w0,%w1,0,1" : "=r"(crypto_int32_y) : "r"(crypto_int32_x) : ); + return crypto_int32_y; +#else + crypto_int32_x &= 1 ^ crypto_int32_optblocker; + return crypto_int32_x; +#endif +} -typedef int8 small; +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_bitinrangepublicpos_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_s) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("sarl %%cl,%0" : "+r"(crypto_int32_x) : "c"(crypto_int32_s) : "cc"); +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("asr %w0,%w0,%w1" : "+r"(crypto_int32_x) : "r"(crypto_int32_s) : ); +#else + crypto_int32_x >>= crypto_int32_s ^ crypto_int32_optblocker; +#endif + return crypto_int32_bottombit_mask(crypto_int32_x); +} -/* F3 is always represented as -1,0,1 */ -/* so ZZ_fromF3 is a no-op */ +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_bitinrangepublicpos_01(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_s) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("sarl %%cl,%0" : "+r"(crypto_int32_x) : "c"(crypto_int32_s) : "cc"); +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("asr %w0,%w0,%w1" : "+r"(crypto_int32_x) : "r"(crypto_int32_s) : ); +#else + crypto_int32_x >>= crypto_int32_s ^ crypto_int32_optblocker; +#endif + return crypto_int32_bottombit_01(crypto_int32_x); +} -/* x must not be close to top int16 */ -static small F3_freeze(int16 x) -{ - return int32_mod_uint14(x+1,3)-1; +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_shlmod(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_s) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("shll %%cl,%0" : "+r"(crypto_int32_x) : "c"(crypto_int32_s) : "cc"); +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("lsl %w0,%w0,%w1" : "+r"(crypto_int32_x) : "r"(crypto_int32_s) : ); +#else + int crypto_int32_k, crypto_int32_l; + for (crypto_int32_l = 0,crypto_int32_k = 1;crypto_int32_k < 32;++crypto_int32_l,crypto_int32_k *= 2) + crypto_int32_x ^= (crypto_int32_x ^ (crypto_int32_x << crypto_int32_k)) & crypto_int32_bitinrangepublicpos_mask(crypto_int32_s,crypto_int32_l); +#endif + return crypto_int32_x; } -/* ----- arithmetic mod q */ +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_shrmod(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_s) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("sarl %%cl,%0" : "+r"(crypto_int32_x) : "c"(crypto_int32_s) : "cc"); +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("asr %w0,%w0,%w1" : "+r"(crypto_int32_x) : "r"(crypto_int32_s) : ); +#else + int crypto_int32_k, crypto_int32_l; + for (crypto_int32_l = 0,crypto_int32_k = 1;crypto_int32_k < 32;++crypto_int32_l,crypto_int32_k *= 2) + crypto_int32_x ^= (crypto_int32_x ^ (crypto_int32_x >> crypto_int32_k)) & crypto_int32_bitinrangepublicpos_mask(crypto_int32_s,crypto_int32_l); +#endif + return crypto_int32_x; +} + +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_bitmod_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_s) { + crypto_int32_x = crypto_int32_shrmod(crypto_int32_x,crypto_int32_s); + return crypto_int32_bottombit_mask(crypto_int32_x); +} + +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_bitmod_01(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_s) { + crypto_int32_x = crypto_int32_shrmod(crypto_int32_x,crypto_int32_s); + return crypto_int32_bottombit_01(crypto_int32_x); +} + +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_nonzero_mask(crypto_int32 crypto_int32_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $-1,%1\n testl %2,%2\n cmovnel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,0\n csetm %w0,ne" : "=r"(crypto_int32_z) : "r"(crypto_int32_x) : "cc"); + return crypto_int32_z; +#else + crypto_int32_x |= -crypto_int32_x; + return crypto_int32_negative_mask(crypto_int32_x); +#endif +} -#define q12 ((q-1)/2) -typedef int16 Fq; -/* always represented as -q12...q12 */ -/* so ZZ_fromFq is a no-op */ +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_nonzero_01(crypto_int32 crypto_int32_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $1,%1\n testl %2,%2\n cmovnel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,0\n cset %w0,ne" : "=r"(crypto_int32_z) : "r"(crypto_int32_x) : "cc"); + return crypto_int32_z; +#else + crypto_int32_x |= -crypto_int32_x; + return crypto_int32_unsigned_topbit_01(crypto_int32_x); +#endif +} -/* x must not be close to top int32 */ -static Fq Fq_freeze(int32 x) -{ - return int32_mod_uint14(x+q12,q)-q12; +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_positive_mask(crypto_int32 crypto_int32_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $-1,%1\n testl %2,%2\n cmovgl %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,0\n csetm %w0,gt" : "=r"(crypto_int32_z) : "r"(crypto_int32_x) : "cc"); + return crypto_int32_z; +#else + crypto_int32 crypto_int32_z = -crypto_int32_x; + crypto_int32_z ^= crypto_int32_x & crypto_int32_z; + return crypto_int32_negative_mask(crypto_int32_z); +#endif } -#ifndef LPR +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_positive_01(crypto_int32 crypto_int32_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $1,%1\n testl %2,%2\n cmovgl %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,0\n cset %w0,gt" : "=r"(crypto_int32_z) : "r"(crypto_int32_x) : "cc"); + return crypto_int32_z; +#else + crypto_int32 crypto_int32_z = -crypto_int32_x; + crypto_int32_z ^= crypto_int32_x & crypto_int32_z; + return crypto_int32_unsigned_topbit_01(crypto_int32_z); +#endif +} -static Fq Fq_recip(Fq a1) -{ - int i = 1; - Fq ai = a1; +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_zero_mask(crypto_int32 crypto_int32_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $-1,%1\n testl %2,%2\n cmovel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,0\n csetm %w0,eq" : "=r"(crypto_int32_z) : "r"(crypto_int32_x) : "cc"); + return crypto_int32_z; +#else + return ~crypto_int32_nonzero_mask(crypto_int32_x); +#endif +} - while (i < q-2) { - ai = Fq_freeze(a1*(int32)ai); - i += 1; - } - return ai; +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_zero_01(crypto_int32 crypto_int32_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $1,%1\n testl %2,%2\n cmovel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,0\n cset %w0,eq" : "=r"(crypto_int32_z) : "r"(crypto_int32_x) : "cc"); + return crypto_int32_z; +#else + return 1-crypto_int32_nonzero_01(crypto_int32_x); +#endif } +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_unequal_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $-1,%1\n cmpl %3,%2\n cmovnel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,%w2\n csetm %w0,ne" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#else + return crypto_int32_nonzero_mask(crypto_int32_x ^ crypto_int32_y); #endif +} -/* ----- Top and Right */ +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_unequal_01(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $1,%1\n cmpl %3,%2\n cmovnel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,%w2\n cset %w0,ne" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#else + return crypto_int32_nonzero_01(crypto_int32_x ^ crypto_int32_y); +#endif +} -#ifdef LPR -#define tau 16 +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_equal_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $-1,%1\n cmpl %3,%2\n cmovel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,%w2\n csetm %w0,eq" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#else + return ~crypto_int32_unequal_mask(crypto_int32_x,crypto_int32_y); +#endif +} -static int8 Top(Fq C) -{ - return (tau1*(int32)(C+tau0)+16384)>>15; +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_equal_01(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $1,%1\n cmpl %3,%2\n cmovel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,%w2\n cset %w0,eq" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#else + return 1-crypto_int32_unequal_01(crypto_int32_x,crypto_int32_y); +#endif } -static Fq Right(int8 T) -{ - return Fq_freeze(tau3*(int32)T-tau2); +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_min(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("cmpl %1,%0\n cmovgl %1,%0" : "+r"(crypto_int32_x) : "r"(crypto_int32_y) : "cc"); + return crypto_int32_x; +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("cmp %w0,%w1\n csel %w0,%w0,%w1,lt" : "+r"(crypto_int32_x) : "r"(crypto_int32_y) : "cc"); + return crypto_int32_x; +#else + crypto_int64 crypto_int32_r = (crypto_int64)crypto_int32_y ^ (crypto_int64)crypto_int32_x; + crypto_int64 crypto_int32_z = (crypto_int64)crypto_int32_y - (crypto_int64)crypto_int32_x; + crypto_int32_z ^= crypto_int32_r & (crypto_int32_z ^ crypto_int32_y); + crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); + crypto_int32_z &= crypto_int32_r; + return crypto_int32_x ^ crypto_int32_z; +#endif } + +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_max(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("cmpl %1,%0\n cmovll %1,%0" : "+r"(crypto_int32_x) : "r"(crypto_int32_y) : "cc"); + return crypto_int32_x; +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("cmp %w0,%w1\n csel %w0,%w1,%w0,lt" : "+r"(crypto_int32_x) : "r"(crypto_int32_y) : "cc"); + return crypto_int32_x; +#else + crypto_int64 crypto_int32_r = (crypto_int64)crypto_int32_y ^ (crypto_int64)crypto_int32_x; + crypto_int64 crypto_int32_z = (crypto_int64)crypto_int32_y - (crypto_int64)crypto_int32_x; + crypto_int32_z ^= crypto_int32_r & (crypto_int32_z ^ crypto_int32_y); + crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); + crypto_int32_z &= crypto_int32_r; + return crypto_int32_y ^ crypto_int32_z; #endif +} -/* ----- small polynomials */ +__attribute__((unused)) +static inline +void crypto_int32_minmax(crypto_int32 *crypto_int32_p,crypto_int32 *crypto_int32_q) { + crypto_int32 crypto_int32_x = *crypto_int32_p; + crypto_int32 crypto_int32_y = *crypto_int32_q; +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmpl %2,%1\n movl %1,%0\n cmovgl %2,%1\n cmovgl %0,%2" : "=&r"(crypto_int32_z), "+&r"(crypto_int32_x), "+r"(crypto_int32_y) : : "cc"); + *crypto_int32_p = crypto_int32_x; + *crypto_int32_q = crypto_int32_y; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_r, crypto_int32_s; + __asm__ ("cmp %w2,%w3\n csel %w0,%w2,%w3,lt\n csel %w1,%w3,%w2,lt" : "=&r"(crypto_int32_r), "=r"(crypto_int32_s) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + *crypto_int32_p = crypto_int32_r; + *crypto_int32_q = crypto_int32_s; +#else + crypto_int64 crypto_int32_r = (crypto_int64)crypto_int32_y ^ (crypto_int64)crypto_int32_x; + crypto_int64 crypto_int32_z = (crypto_int64)crypto_int32_y - (crypto_int64)crypto_int32_x; + crypto_int32_z ^= crypto_int32_r & (crypto_int32_z ^ crypto_int32_y); + crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); + crypto_int32_z &= crypto_int32_r; + crypto_int32_x ^= crypto_int32_z; + crypto_int32_y ^= crypto_int32_z; + *crypto_int32_p = crypto_int32_x; + *crypto_int32_q = crypto_int32_y; +#endif +} -#ifndef LPR - -/* 0 if Weightw_is(r), else -1 */ -static int Weightw_mask(small *r) -{ - int weight = 0; - int i; - - for (i = 0;i < p;++i) weight += r[i]&1; - return int16_nonzero_mask(weight-w); +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_smaller_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $-1,%1\n cmpl %3,%2\n cmovll %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,%w2\n csetm %w0,lt" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#else + crypto_int32 crypto_int32_r = crypto_int32_x ^ crypto_int32_y; + crypto_int32 crypto_int32_z = crypto_int32_x - crypto_int32_y; + crypto_int32_z ^= crypto_int32_r & (crypto_int32_z ^ crypto_int32_x); + return crypto_int32_negative_mask(crypto_int32_z); +#endif } -/* R3_fromR(R_fromRq(r)) */ -static void R3_fromRq(small *out,const Fq *r) -{ - int i; - for (i = 0;i < p;++i) out[i] = F3_freeze(r[i]); +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_smaller_01(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $1,%1\n cmpl %3,%2\n cmovll %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,%w2\n cset %w0,lt" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#else + crypto_int32 crypto_int32_r = crypto_int32_x ^ crypto_int32_y; + crypto_int32 crypto_int32_z = crypto_int32_x - crypto_int32_y; + crypto_int32_z ^= crypto_int32_r & (crypto_int32_z ^ crypto_int32_x); + return crypto_int32_unsigned_topbit_01(crypto_int32_z); +#endif } -/* h = f*g in the ring R3 */ -static void R3_mult(small *h,const small *f,const small *g) -{ - small fg[p+p-1]; - small result; - int i,j; - - for (i = 0;i < p;++i) { - result = 0; - for (j = 0;j <= i;++j) result = F3_freeze(result+f[j]*g[i-j]); - fg[i] = result; - } - for (i = p;i < p+p-1;++i) { - result = 0; - for (j = i-p+1;j < p;++j) result = F3_freeze(result+f[j]*g[i-j]); - fg[i] = result; - } - - for (i = p+p-2;i >= p;--i) { - fg[i-p] = F3_freeze(fg[i-p]+fg[i]); - fg[i-p+1] = F3_freeze(fg[i-p+1]+fg[i]); - } - - for (i = 0;i < p;++i) h[i] = fg[i]; +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_leq_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $-1,%1\n cmpl %3,%2\n cmovlel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,%w2\n csetm %w0,le" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#else + return ~crypto_int32_smaller_mask(crypto_int32_y,crypto_int32_x); +#endif } -/* returns 0 if recip succeeded; else -1 */ -static int R3_recip(small *out,const small *in) -{ - small f[p+1],g[p+1],v[p+1],r[p+1]; - int i,loop,delta; - int sign,swap,t; - - for (i = 0;i < p+1;++i) v[i] = 0; - for (i = 0;i < p+1;++i) r[i] = 0; - r[0] = 1; - for (i = 0;i < p;++i) f[i] = 0; - f[0] = 1; f[p-1] = f[p] = -1; - for (i = 0;i < p;++i) g[p-1-i] = in[i]; - g[p] = 0; - - delta = 1; - - for (loop = 0;loop < 2*p-1;++loop) { - for (i = p;i > 0;--i) v[i] = v[i-1]; - v[0] = 0; - - sign = -g[0]*f[0]; - swap = int16_negative_mask(-delta) & int16_nonzero_mask(g[0]); - delta ^= swap&(delta^-delta); - delta += 1; - - for (i = 0;i < p+1;++i) { - t = swap&(f[i]^g[i]); f[i] ^= t; g[i] ^= t; - t = swap&(v[i]^r[i]); v[i] ^= t; r[i] ^= t; - } - - for (i = 0;i < p+1;++i) g[i] = F3_freeze(g[i]+sign*f[i]); - for (i = 0;i < p+1;++i) r[i] = F3_freeze(r[i]+sign*v[i]); - - for (i = 0;i < p;++i) g[i] = g[i+1]; - g[p] = 0; - } - - sign = f[0]; - for (i = 0;i < p;++i) out[i] = sign*v[p-1-i]; - - return int16_nonzero_mask(delta); +__attribute__((unused)) +static inline +crypto_int32 crypto_int32_leq_01(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 crypto_int32_q,crypto_int32_z; + __asm__ ("xorl %0,%0\n movl $1,%1\n cmpl %3,%2\n cmovlel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int32 crypto_int32_z; + __asm__ ("cmp %w1,%w2\n cset %w0,le" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); + return crypto_int32_z; +#else + return 1-crypto_int32_smaller_01(crypto_int32_y,crypto_int32_x); +#endif } +__attribute__((unused)) +static inline +int crypto_int32_ones_num(crypto_int32 crypto_int32_x) { + crypto_int32_unsigned crypto_int32_y = crypto_int32_x; + const crypto_int32 C0 = 0x55555555; + const crypto_int32 C1 = 0x33333333; + const crypto_int32 C2 = 0x0f0f0f0f; + crypto_int32_y -= ((crypto_int32_y >> 1) & C0); + crypto_int32_y = (crypto_int32_y & C1) + ((crypto_int32_y >> 2) & C1); + crypto_int32_y = (crypto_int32_y + (crypto_int32_y >> 4)) & C2; + crypto_int32_y += crypto_int32_y >> 8; + crypto_int32_y = (crypto_int32_y + (crypto_int32_y >> 16)) & 0xff; + return crypto_int32_y; +} + +__attribute__((unused)) +static inline +int crypto_int32_bottomzeros_num(crypto_int32 crypto_int32_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int32 fallback = 32; + __asm__ ("bsfl %0,%0\n cmovel %1,%0" : "+&r"(crypto_int32_x) : "r"(fallback) : "cc"); + return crypto_int32_x; +#elif defined(__GNUC__) && defined(__aarch64__) + int64_t crypto_int32_y; + __asm__ ("rbit %w0,%w1\n clz %w0,%w0" : "=r"(crypto_int32_y) : "r"(crypto_int32_x) : ); + return crypto_int32_y; +#else + crypto_int32 crypto_int32_y = crypto_int32_x ^ (crypto_int32_x-1); + crypto_int32_y = ((crypto_int32) crypto_int32_y) >> 1; + crypto_int32_y &= ~(crypto_int32_x & (((crypto_int32) 1) << (32-1))); + return crypto_int32_ones_num(crypto_int32_y); #endif - -/* ----- polynomials mod q */ - -/* h = f*g in the ring Rq */ -static void Rq_mult_small(Fq *h,const Fq *f,const small *g) -{ - Fq fg[p+p-1]; - Fq result; - int i,j; - - for (i = 0;i < p;++i) { - result = 0; - for (j = 0;j <= i;++j) result = Fq_freeze(result+f[j]*(int32)g[i-j]); - fg[i] = result; - } - for (i = p;i < p+p-1;++i) { - result = 0; - for (j = i-p+1;j < p;++j) result = Fq_freeze(result+f[j]*(int32)g[i-j]); - fg[i] = result; - } - - for (i = p+p-2;i >= p;--i) { - fg[i-p] = Fq_freeze(fg[i-p]+fg[i]); - fg[i-p+1] = Fq_freeze(fg[i-p+1]+fg[i]); - } - - for (i = 0;i < p;++i) h[i] = fg[i]; } -#ifndef LPR - -/* h = 3f in Rq */ -static void Rq_mult3(Fq *h,const Fq *f) -{ - int i; +#endif - for (i = 0;i < p;++i) h[i] = Fq_freeze(3*f[i]); +/* from supercop-20240808/cryptoint/crypto_int64.h */ +/* auto-generated: cd cryptoint; ./autogen */ +/* cryptoint 20240806 */ + +#ifndef crypto_int64_h +#define crypto_int64_h + +#define crypto_int64 int64_t +#define crypto_int64_unsigned uint64_t + + + +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_load(const unsigned char *crypto_int64_s) { + crypto_int64 crypto_int64_z = 0; + crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 0; + crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 8; + crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 16; + crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 24; + crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 32; + crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 40; + crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 48; + crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 56; + return crypto_int64_z; +} + +__attribute__((unused)) +static inline +void crypto_int64_store(unsigned char *crypto_int64_s,crypto_int64 crypto_int64_x) { + *crypto_int64_s++ = crypto_int64_x >> 0; + *crypto_int64_s++ = crypto_int64_x >> 8; + *crypto_int64_s++ = crypto_int64_x >> 16; + *crypto_int64_s++ = crypto_int64_x >> 24; + *crypto_int64_s++ = crypto_int64_x >> 32; + *crypto_int64_s++ = crypto_int64_x >> 40; + *crypto_int64_s++ = crypto_int64_x >> 48; + *crypto_int64_s++ = crypto_int64_x >> 56; +} + +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_negative_mask(crypto_int64 crypto_int64_x) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("sarq $63,%0" : "+r"(crypto_int64_x) : : "cc"); + return crypto_int64_x; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_y; + __asm__ ("asr %0,%1,63" : "=r"(crypto_int64_y) : "r"(crypto_int64_x) : ); + return crypto_int64_y; +#else + crypto_int64_x >>= 64-6; + crypto_int64_x ^= crypto_int64_optblocker; + crypto_int64_x >>= 5; + return crypto_int64_x; +#endif } -/* out = 1/(3*in) in Rq */ -/* returns 0 if recip succeeded; else -1 */ -static int Rq_recip3(Fq *out,const small *in) -{ - Fq f[p+1],g[p+1],v[p+1],r[p+1]; - int i,loop,delta; - int swap,t; - int32 f0,g0; - Fq scale; - - for (i = 0;i < p+1;++i) v[i] = 0; - for (i = 0;i < p+1;++i) r[i] = 0; - r[0] = Fq_recip(3); - for (i = 0;i < p;++i) f[i] = 0; - f[0] = 1; f[p-1] = f[p] = -1; - for (i = 0;i < p;++i) g[p-1-i] = in[i]; - g[p] = 0; - - delta = 1; - - for (loop = 0;loop < 2*p-1;++loop) { - for (i = p;i > 0;--i) v[i] = v[i-1]; - v[0] = 0; - - swap = int16_negative_mask(-delta) & int16_nonzero_mask(g[0]); - delta ^= swap&(delta^-delta); - delta += 1; - - for (i = 0;i < p+1;++i) { - t = swap&(f[i]^g[i]); f[i] ^= t; g[i] ^= t; - t = swap&(v[i]^r[i]); v[i] ^= t; r[i] ^= t; - } - - f0 = f[0]; - g0 = g[0]; - for (i = 0;i < p+1;++i) g[i] = Fq_freeze(f0*g[i]-g0*f[i]); - for (i = 0;i < p+1;++i) r[i] = Fq_freeze(f0*r[i]-g0*v[i]); +__attribute__((unused)) +static inline +crypto_int64_unsigned crypto_int64_unsigned_topbit_01(crypto_int64_unsigned crypto_int64_x) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("shrq $63,%0" : "+r"(crypto_int64_x) : : "cc"); + return crypto_int64_x; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_y; + __asm__ ("lsr %0,%1,63" : "=r"(crypto_int64_y) : "r"(crypto_int64_x) : ); + return crypto_int64_y; +#else + crypto_int64_x >>= 64-6; + crypto_int64_x ^= crypto_int64_optblocker; + crypto_int64_x >>= 5; + return crypto_int64_x; +#endif +} - for (i = 0;i < p;++i) g[i] = g[i+1]; - g[p] = 0; - } +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_negative_01(crypto_int64 crypto_int64_x) { + return crypto_int64_unsigned_topbit_01(crypto_int64_x); +} - scale = Fq_recip(f[0]); - for (i = 0;i < p;++i) out[i] = Fq_freeze(scale*(int32)v[p-1-i]); +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_topbit_mask(crypto_int64 crypto_int64_x) { + return crypto_int64_negative_mask(crypto_int64_x); +} - return int16_nonzero_mask(delta); +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_topbit_01(crypto_int64 crypto_int64_x) { + return crypto_int64_unsigned_topbit_01(crypto_int64_x); } +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_bottombit_mask(crypto_int64 crypto_int64_x) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("andq $1,%0" : "+r"(crypto_int64_x) : : "cc"); + return -crypto_int64_x; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_y; + __asm__ ("sbfx %0,%1,0,1" : "=r"(crypto_int64_y) : "r"(crypto_int64_x) : ); + return crypto_int64_y; +#else + crypto_int64_x &= 1 ^ crypto_int64_optblocker; + return -crypto_int64_x; #endif - -/* ----- rounded polynomials mod q */ - -static void Round(Fq *out,const Fq *a) -{ - int i; - for (i = 0;i < p;++i) out[i] = a[i]-F3_freeze(a[i]); } -/* ----- sorting to generate short polynomial */ - -static void Short_fromlist(small *out,const uint32 *in) -{ - uint32 L[p]; - int i; - - for (i = 0;i < w;++i) L[i] = in[i]&(uint32)-2; - for (i = w;i < p;++i) L[i] = (in[i]&(uint32)-3)|1; - crypto_sort_uint32(L,p); - for (i = 0;i < p;++i) out[i] = (L[i]&3)-1; +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_bottombit_01(crypto_int64 crypto_int64_x) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("andq $1,%0" : "+r"(crypto_int64_x) : : "cc"); + return crypto_int64_x; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_y; + __asm__ ("ubfx %0,%1,0,1" : "=r"(crypto_int64_y) : "r"(crypto_int64_x) : ); + return crypto_int64_y; +#else + crypto_int64_x &= 1 ^ crypto_int64_optblocker; + return crypto_int64_x; +#endif } -/* ----- underlying hash function */ - -#define Hash_bytes 32 - -/* e.g., b = 0 means out = Hash0(in) */ -static void Hash_prefix(unsigned char *out,int b,const unsigned char *in,int inlen) -{ - unsigned char x[inlen+1]; - unsigned char h[64]; - int i; - - x[0] = b; - for (i = 0;i < inlen;++i) x[i+1] = in[i]; - crypto_hash_sha512(h,x,inlen+1); - for (i = 0;i < 32;++i) out[i] = h[i]; +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_bitinrangepublicpos_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_s) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("sarq %%cl,%0" : "+r"(crypto_int64_x) : "c"(crypto_int64_s) : "cc"); +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("asr %0,%0,%1" : "+r"(crypto_int64_x) : "r"(crypto_int64_s) : ); +#else + crypto_int64_x >>= crypto_int64_s ^ crypto_int64_optblocker; +#endif + return crypto_int64_bottombit_mask(crypto_int64_x); } -/* ----- higher-level randomness */ - -static uint32 urandom32(void) -{ - unsigned char c[4]; - uint32 out[4]; - - randombytes(c,4); - out[0] = (uint32)c[0]; - out[1] = ((uint32)c[1])<<8; - out[2] = ((uint32)c[2])<<16; - out[3] = ((uint32)c[3])<<24; - return out[0]+out[1]+out[2]+out[3]; +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_bitinrangepublicpos_01(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_s) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("sarq %%cl,%0" : "+r"(crypto_int64_x) : "c"(crypto_int64_s) : "cc"); +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("asr %0,%0,%1" : "+r"(crypto_int64_x) : "r"(crypto_int64_s) : ); +#else + crypto_int64_x >>= crypto_int64_s ^ crypto_int64_optblocker; +#endif + return crypto_int64_bottombit_01(crypto_int64_x); } -static void Short_random(small *out) -{ - uint32 L[p]; - int i; - - for (i = 0;i < p;++i) L[i] = urandom32(); - Short_fromlist(out,L); +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_shlmod(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_s) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("shlq %%cl,%0" : "+r"(crypto_int64_x) : "c"(crypto_int64_s) : "cc"); +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("lsl %0,%0,%1" : "+r"(crypto_int64_x) : "r"(crypto_int64_s) : ); +#else + int crypto_int64_k, crypto_int64_l; + for (crypto_int64_l = 0,crypto_int64_k = 1;crypto_int64_k < 64;++crypto_int64_l,crypto_int64_k *= 2) + crypto_int64_x ^= (crypto_int64_x ^ (crypto_int64_x << crypto_int64_k)) & crypto_int64_bitinrangepublicpos_mask(crypto_int64_s,crypto_int64_l); +#endif + return crypto_int64_x; } -#ifndef LPR - -static void Small_random(small *out) -{ - int i; - - for (i = 0;i < p;++i) out[i] = (((urandom32()&0x3fffffff)*3)>>30)-1; +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_shrmod(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_s) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("sarq %%cl,%0" : "+r"(crypto_int64_x) : "c"(crypto_int64_s) : "cc"); +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("asr %0,%0,%1" : "+r"(crypto_int64_x) : "r"(crypto_int64_s) : ); +#else + int crypto_int64_k, crypto_int64_l; + for (crypto_int64_l = 0,crypto_int64_k = 1;crypto_int64_k < 64;++crypto_int64_l,crypto_int64_k *= 2) + crypto_int64_x ^= (crypto_int64_x ^ (crypto_int64_x >> crypto_int64_k)) & crypto_int64_bitinrangepublicpos_mask(crypto_int64_s,crypto_int64_l); +#endif + return crypto_int64_x; +} + +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_bitmod_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_s) { + crypto_int64_x = crypto_int64_shrmod(crypto_int64_x,crypto_int64_s); + return crypto_int64_bottombit_mask(crypto_int64_x); +} + +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_bitmod_01(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_s) { + crypto_int64_x = crypto_int64_shrmod(crypto_int64_x,crypto_int64_s); + return crypto_int64_bottombit_01(crypto_int64_x); +} + +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_nonzero_mask(crypto_int64 crypto_int64_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $-1,%1\n testq %2,%2\n cmovneq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,0\n csetm %0,ne" : "=r"(crypto_int64_z) : "r"(crypto_int64_x) : "cc"); + return crypto_int64_z; +#else + crypto_int64_x |= -crypto_int64_x; + return crypto_int64_negative_mask(crypto_int64_x); +#endif } +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_nonzero_01(crypto_int64 crypto_int64_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $1,%1\n testq %2,%2\n cmovneq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,0\n cset %0,ne" : "=r"(crypto_int64_z) : "r"(crypto_int64_x) : "cc"); + return crypto_int64_z; +#else + crypto_int64_x |= -crypto_int64_x; + return crypto_int64_unsigned_topbit_01(crypto_int64_x); #endif - -/* ----- Streamlined NTRU Prime Core */ - -#ifndef LPR - -/* h,(f,ginv) = KeyGen() */ -static void KeyGen(Fq *h,small *f,small *ginv) -{ - small g[p]; - Fq finv[p]; - - for (;;) { - Small_random(g); - if (R3_recip(ginv,g) == 0) break; - } - Short_random(f); - Rq_recip3(finv,f); /* always works */ - Rq_mult_small(h,finv,g); } -/* c = Encrypt(r,h) */ -static void Encrypt(Fq *c,const small *r,const Fq *h) -{ - Fq hr[p]; +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_positive_mask(crypto_int64 crypto_int64_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $-1,%1\n testq %2,%2\n cmovgq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,0\n csetm %0,gt" : "=r"(crypto_int64_z) : "r"(crypto_int64_x) : "cc"); + return crypto_int64_z; +#else + crypto_int64 crypto_int64_z = -crypto_int64_x; + crypto_int64_z ^= crypto_int64_x & crypto_int64_z; + return crypto_int64_negative_mask(crypto_int64_z); +#endif +} - Rq_mult_small(hr,h,r); - Round(c,hr); +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_positive_01(crypto_int64 crypto_int64_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $1,%1\n testq %2,%2\n cmovgq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,0\n cset %0,gt" : "=r"(crypto_int64_z) : "r"(crypto_int64_x) : "cc"); + return crypto_int64_z; +#else + crypto_int64 crypto_int64_z = -crypto_int64_x; + crypto_int64_z ^= crypto_int64_x & crypto_int64_z; + return crypto_int64_unsigned_topbit_01(crypto_int64_z); +#endif } -/* r = Decrypt(c,(f,ginv)) */ -static void Decrypt(small *r,const Fq *c,const small *f,const small *ginv) -{ - Fq cf[p]; - Fq cf3[p]; - small e[p]; - small ev[p]; - int mask; - int i; +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_zero_mask(crypto_int64 crypto_int64_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $-1,%1\n testq %2,%2\n cmoveq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,0\n csetm %0,eq" : "=r"(crypto_int64_z) : "r"(crypto_int64_x) : "cc"); + return crypto_int64_z; +#else + return ~crypto_int64_nonzero_mask(crypto_int64_x); +#endif +} - Rq_mult_small(cf,c,f); - Rq_mult3(cf3,cf); - R3_fromRq(e,cf3); - R3_mult(ev,e,ginv); +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_zero_01(crypto_int64 crypto_int64_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $1,%1\n testq %2,%2\n cmoveq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,0\n cset %0,eq" : "=r"(crypto_int64_z) : "r"(crypto_int64_x) : "cc"); + return crypto_int64_z; +#else + return 1-crypto_int64_nonzero_01(crypto_int64_x); +#endif +} - mask = Weightw_mask(ev); /* 0 if weight w, else -1 */ - for (i = 0;i < w;++i) r[i] = ((ev[i]^1)&~mask)^1; - for (i = w;i < p;++i) r[i] = ev[i]&~mask; +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_unequal_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $-1,%1\n cmpq %3,%2\n cmovneq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,%2\n csetm %0,ne" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#else + return crypto_int64_nonzero_mask(crypto_int64_x ^ crypto_int64_y); +#endif } +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_unequal_01(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $1,%1\n cmpq %3,%2\n cmovneq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,%2\n cset %0,ne" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#else + return crypto_int64_nonzero_01(crypto_int64_x ^ crypto_int64_y); #endif +} -/* ----- NTRU LPRime Core */ +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_equal_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $-1,%1\n cmpq %3,%2\n cmoveq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,%2\n csetm %0,eq" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#else + return ~crypto_int64_unequal_mask(crypto_int64_x,crypto_int64_y); +#endif +} -#ifdef LPR +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_equal_01(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $1,%1\n cmpq %3,%2\n cmoveq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,%2\n cset %0,eq" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#else + return 1-crypto_int64_unequal_01(crypto_int64_x,crypto_int64_y); +#endif +} -/* (G,A),a = KeyGen(G); leaves G unchanged */ -static void KeyGen(Fq *A,small *a,const Fq *G) -{ - Fq aG[p]; +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_min(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("cmpq %1,%0\n cmovgq %1,%0" : "+r"(crypto_int64_x) : "r"(crypto_int64_y) : "cc"); + return crypto_int64_x; +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("cmp %0,%1\n csel %0,%0,%1,lt" : "+r"(crypto_int64_x) : "r"(crypto_int64_y) : "cc"); + return crypto_int64_x; +#else + crypto_int64 crypto_int64_r = crypto_int64_y ^ crypto_int64_x; + crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x; + crypto_int64_z ^= crypto_int64_r & (crypto_int64_z ^ crypto_int64_y); + crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z); + crypto_int64_z &= crypto_int64_r; + return crypto_int64_x ^ crypto_int64_z; +#endif +} - Short_random(a); - Rq_mult_small(aG,G,a); - Round(A,aG); +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_max(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { +#if defined(__GNUC__) && defined(__x86_64__) + __asm__ ("cmpq %1,%0\n cmovlq %1,%0" : "+r"(crypto_int64_x) : "r"(crypto_int64_y) : "cc"); + return crypto_int64_x; +#elif defined(__GNUC__) && defined(__aarch64__) + __asm__ ("cmp %0,%1\n csel %0,%1,%0,lt" : "+r"(crypto_int64_x) : "r"(crypto_int64_y) : "cc"); + return crypto_int64_x; +#else + crypto_int64 crypto_int64_r = crypto_int64_y ^ crypto_int64_x; + crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x; + crypto_int64_z ^= crypto_int64_r & (crypto_int64_z ^ crypto_int64_y); + crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z); + crypto_int64_z &= crypto_int64_r; + return crypto_int64_y ^ crypto_int64_z; +#endif } -/* B,T = Encrypt(r,(G,A),b) */ -static void Encrypt(Fq *B,int8 *T,const int8 *r,const Fq *G,const Fq *A,const small *b) -{ - Fq bG[p]; - Fq bA[p]; - int i; +__attribute__((unused)) +static inline +void crypto_int64_minmax(crypto_int64 *crypto_int64_p,crypto_int64 *crypto_int64_q) { + crypto_int64 crypto_int64_x = *crypto_int64_p; + crypto_int64 crypto_int64_y = *crypto_int64_q; +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmpq %2,%1\n movq %1,%0\n cmovgq %2,%1\n cmovgq %0,%2" : "=&r"(crypto_int64_z), "+&r"(crypto_int64_x), "+r"(crypto_int64_y) : : "cc"); + *crypto_int64_p = crypto_int64_x; + *crypto_int64_q = crypto_int64_y; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_r, crypto_int64_s; + __asm__ ("cmp %2,%3\n csel %0,%2,%3,lt\n csel %1,%3,%2,lt" : "=&r"(crypto_int64_r), "=r"(crypto_int64_s) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + *crypto_int64_p = crypto_int64_r; + *crypto_int64_q = crypto_int64_s; +#else + crypto_int64 crypto_int64_r = crypto_int64_y ^ crypto_int64_x; + crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x; + crypto_int64_z ^= crypto_int64_r & (crypto_int64_z ^ crypto_int64_y); + crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z); + crypto_int64_z &= crypto_int64_r; + crypto_int64_x ^= crypto_int64_z; + crypto_int64_y ^= crypto_int64_z; + *crypto_int64_p = crypto_int64_x; + *crypto_int64_q = crypto_int64_y; +#endif +} - Rq_mult_small(bG,G,b); - Round(B,bG); - Rq_mult_small(bA,A,b); - for (i = 0;i < I;++i) T[i] = Top(Fq_freeze(bA[i]+r[i]*q12)); +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_smaller_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $-1,%1\n cmpq %3,%2\n cmovlq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,%2\n csetm %0,lt" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#else + crypto_int64 crypto_int64_r = crypto_int64_x ^ crypto_int64_y; + crypto_int64 crypto_int64_z = crypto_int64_x - crypto_int64_y; + crypto_int64_z ^= crypto_int64_r & (crypto_int64_z ^ crypto_int64_x); + return crypto_int64_negative_mask(crypto_int64_z); +#endif } -/* r = Decrypt((B,T),a) */ -static void Decrypt(int8 *r,const Fq *B,const int8 *T,const small *a) -{ - Fq aB[p]; - int i; +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_smaller_01(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $1,%1\n cmpq %3,%2\n cmovlq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,%2\n cset %0,lt" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#else + crypto_int64 crypto_int64_r = crypto_int64_x ^ crypto_int64_y; + crypto_int64 crypto_int64_z = crypto_int64_x - crypto_int64_y; + crypto_int64_z ^= crypto_int64_r & (crypto_int64_z ^ crypto_int64_x); + return crypto_int64_unsigned_topbit_01(crypto_int64_z); +#endif +} - Rq_mult_small(aB,B,a); - for (i = 0;i < I;++i) - r[i] = -int16_negative_mask(Fq_freeze(Right(T[i])-aB[i]+4*w+1)); +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_leq_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $-1,%1\n cmpq %3,%2\n cmovleq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,%2\n csetm %0,le" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#else + return ~crypto_int64_smaller_mask(crypto_int64_y,crypto_int64_x); +#endif } +__attribute__((unused)) +static inline +crypto_int64 crypto_int64_leq_01(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 crypto_int64_q,crypto_int64_z; + __asm__ ("xorq %0,%0\n movq $1,%1\n cmpq %3,%2\n cmovleq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#elif defined(__GNUC__) && defined(__aarch64__) + crypto_int64 crypto_int64_z; + __asm__ ("cmp %1,%2\n cset %0,le" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); + return crypto_int64_z; +#else + return 1-crypto_int64_smaller_01(crypto_int64_y,crypto_int64_x); #endif +} -/* ----- encoding I-bit inputs */ +__attribute__((unused)) +static inline +int crypto_int64_ones_num(crypto_int64 crypto_int64_x) { + crypto_int64_unsigned crypto_int64_y = crypto_int64_x; + const crypto_int64 C0 = 0x5555555555555555; + const crypto_int64 C1 = 0x3333333333333333; + const crypto_int64 C2 = 0x0f0f0f0f0f0f0f0f; + crypto_int64_y -= ((crypto_int64_y >> 1) & C0); + crypto_int64_y = (crypto_int64_y & C1) + ((crypto_int64_y >> 2) & C1); + crypto_int64_y = (crypto_int64_y + (crypto_int64_y >> 4)) & C2; + crypto_int64_y += crypto_int64_y >> 8; + crypto_int64_y += crypto_int64_y >> 16; + crypto_int64_y = (crypto_int64_y + (crypto_int64_y >> 32)) & 0xff; + return crypto_int64_y; +} + +__attribute__((unused)) +static inline +int crypto_int64_bottomzeros_num(crypto_int64 crypto_int64_x) { +#if defined(__GNUC__) && defined(__x86_64__) + crypto_int64 fallback = 64; + __asm__ ("bsfq %0,%0\n cmoveq %1,%0" : "+&r"(crypto_int64_x) : "r"(fallback) : "cc"); + return crypto_int64_x; +#elif defined(__GNUC__) && defined(__aarch64__) + int64_t crypto_int64_y; + __asm__ ("rbit %0,%1\n clz %0,%0" : "=r"(crypto_int64_y) : "r"(crypto_int64_x) : ); + return crypto_int64_y; +#else + crypto_int64 crypto_int64_y = crypto_int64_x ^ (crypto_int64_x-1); + crypto_int64_y = ((crypto_int64) crypto_int64_y) >> 1; + crypto_int64_y &= ~(crypto_int64_x & (((crypto_int64) 1) << (64-1))); + return crypto_int64_ones_num(crypto_int64_y); +#endif +} -#ifdef LPR +#endif -#define Inputs_bytes (I/8) -typedef int8 Inputs[I]; /* passed by reference */ +/* from supercop-20240808/crypto_sort/int32/portable4/sort.c */ +#define int32_MINMAX(a,b) crypto_int32_minmax(&a,&b) -static void Inputs_encode(unsigned char *s,const Inputs r) +static void crypto_sort_int32(void *array,long long n) { - int i; - for (i = 0;i < Inputs_bytes;++i) s[i] = 0; - for (i = 0;i < I;++i) s[i>>3] |= r[i]<<(i&7); -} - -#endif + long long top,p,q,r,i,j; + int32 *x = array; -/* ----- Expand */ + if (n < 2) return; + top = 1; + while (top < n - top) top += top; -#ifdef LPR + for (p = top;p >= 1;p >>= 1) { + i = 0; + while (i + 2 * p <= n) { + for (j = i;j < i + p;++j) + int32_MINMAX(x[j],x[j+p]); + i += 2 * p; + } + for (j = i;j < n - p;++j) + int32_MINMAX(x[j],x[j+p]); -static const unsigned char aes_nonce[16] = {0}; + i = 0; + j = 0; + for (q = top;q > p;q >>= 1) { + if (j != i) for (;;) { + if (j == n - q) goto done; + int32 a = x[j + p]; + for (r = q;r > p;r >>= 1) + int32_MINMAX(a,x[j + r]); + x[j + p] = a; + ++j; + if (j == i + p) { + i += 2 * p; + break; + } + } + while (i + p <= n - q) { + for (j = i;j < i + p;++j) { + int32 a = x[j + p]; + for (r = q;r > p;r >>= 1) + int32_MINMAX(a,x[j+r]); + x[j + p] = a; + } + i += 2 * p; + } + /* now i + p > n - q */ + j = i; + while (j < n - q) { + int32 a = x[j + p]; + for (r = q;r > p;r >>= 1) + int32_MINMAX(a,x[j+r]); + x[j + p] = a; + ++j; + } -static void Expand(uint32 *L,const unsigned char *k) -{ - int i; - crypto_stream_aes256ctr((unsigned char *) L,4*p,aes_nonce,k); - for (i = 0;i < p;++i) { - uint32 L0 = ((unsigned char *) L)[4*i]; - uint32 L1 = ((unsigned char *) L)[4*i+1]; - uint32 L2 = ((unsigned char *) L)[4*i+2]; - uint32 L3 = ((unsigned char *) L)[4*i+3]; - L[i] = L0+(L1<<8)+(L2<<16)+(L3<<24); + done: ; + } } } -#endif - -/* ----- Seeds */ +/* from supercop-20240808/crypto_sort/uint32/useint32/sort.c */ -#ifdef LPR - -#define Seeds_bytes 32 +/* can save time by vectorizing xor loops */ +/* can save time by integrating xor loops with int32_sort */ -static void Seeds_random(unsigned char *s) +static void crypto_sort_uint32(void *array,long long n) { - randombytes(s,Seeds_bytes); + crypto_uint32 *x = array; + long long j; + for (j = 0;j < n;++j) x[j] ^= 0x80000000; + crypto_sort_int32(array,n); + for (j = 0;j < n;++j) x[j] ^= 0x80000000; } -#endif - -/* ----- Generator, HashShort */ +/* from supercop-20240808/crypto_kem/sntrup761/compact/kem.c */ +// 20240806 djb: some automated conversion to cryptoint -#ifdef LPR - -/* G = Generator(k) */ -static void Generator(Fq *G,const unsigned char *k) -{ - uint32 L[p]; - int i; +#define p 761 +#define q 4591 +#define w 286 +#define q12 ((q - 1) / 2) +typedef int8_t small; +typedef int16_t Fq; +#define Hash_bytes 32 +#define Small_bytes ((p + 3) / 4) +typedef small Inputs[p]; +#define SecretKeys_bytes (2 * Small_bytes) +#define Confirm_bytes 32 - Expand(L,k); - for (i = 0;i < p;++i) G[i] = uint32_mod_uint14(L[i],q)-q12; +static small F3_freeze(int16_t x) { return x - 3 * ((10923 * x + 16384) >> 15); } + +static Fq Fq_freeze(int32_t x) { + const int32_t q16 = (0x10000 + q / 2) / q; + const int32_t q20 = (0x100000 + q / 2) / q; + const int32_t q28 = (0x10000000 + q / 2) / q; + x -= q * ((q16 * x) >> 16); + x -= q * ((q20 * x) >> 20); + return x - q * ((q28 * x + 0x8000000) >> 28); +} + +static int Weightw_mask(small *r) { + int i, weight = 0; + for (i = 0; i < p; ++i) weight += crypto_int64_bottombit_01(r[i]); + return crypto_int16_nonzero_mask(weight - w); +} + +static void uint32_divmod_uint14(uint32_t *Q, uint16_t *r, uint32_t x, uint16_t m) { + uint32_t qpart, mask, v = 0x80000000 / m; + qpart = (x * (uint64_t)v) >> 31; + x -= qpart * m; + *Q = qpart; + qpart = (x * (uint64_t)v) >> 31; + x -= qpart * m; + *Q += qpart; + x -= m; + *Q += 1; + mask = crypto_int32_negative_mask(x); + x += mask & (uint32_t)m; + *Q += mask; + *r = x; } -/* out = HashShort(r) */ -static void HashShort(small *out,const Inputs r) -{ - unsigned char s[Inputs_bytes]; - unsigned char h[Hash_bytes]; - uint32 L[p]; - - Inputs_encode(s,r); - Hash_prefix(h,5,s,sizeof s); - Expand(L,h); - Short_fromlist(out,L); +static uint16_t uint32_mod_uint14(uint32_t x, uint16_t m) { + uint32_t Q; + uint16_t r; + uint32_divmod_uint14(&Q, &r, x, m); + return r; } -#endif - -/* ----- NTRU LPRime Expand */ - -#ifdef LPR - -/* (S,A),a = XKeyGen() */ -static void XKeyGen(unsigned char *S,Fq *A,small *a) -{ - Fq G[p]; - - Seeds_random(S); - Generator(G,S); - KeyGen(A,a,G); +static void Encode(unsigned char *out, const uint16_t *R, const uint16_t *M, long long len) { + if (len == 1) { + uint16_t r = R[0], m = M[0]; + while (m > 1) { + *out++ = r; + r >>= 8; + m = (m + 255) >> 8; + } + } + if (len > 1) { + uint16_t R2[(len + 1) / 2], M2[(len + 1) / 2]; + long long i; + for (i = 0; i < len - 1; i += 2) { + uint32_t m0 = M[i]; + uint32_t r = R[i] + R[i + 1] * m0; + uint32_t m = M[i + 1] * m0; + while (m >= 16384) { + *out++ = r; + r >>= 8; + m = (m + 255) >> 8; + } + R2[i / 2] = r; + M2[i / 2] = m; + } + if (i < len) { + R2[i / 2] = R[i]; + M2[i / 2] = M[i]; + } + Encode(out, R2, M2, (len + 1) / 2); + } } -/* B,T = XEncrypt(r,(S,A)) */ -static void XEncrypt(Fq *B,int8 *T,const int8 *r,const unsigned char *S,const Fq *A) -{ - Fq G[p]; - small b[p]; - - Generator(G,S); - HashShort(b,r); - Encrypt(B,T,r,G,A,b); +static void Decode(uint16_t *out, const unsigned char *S, const uint16_t *M, long long len) { + if (len == 1) { + if (M[0] == 1) + *out = 0; + else if (M[0] <= 256) + *out = uint32_mod_uint14(S[0], M[0]); + else + *out = uint32_mod_uint14(S[0] + (((uint16_t)S[1]) << 8), M[0]); + } + if (len > 1) { + uint16_t R2[(len + 1) / 2], M2[(len + 1) / 2], bottomr[len / 2]; + uint32_t bottomt[len / 2]; + long long i; + for (i = 0; i < len - 1; i += 2) { + uint32_t m = M[i] * (uint32_t)M[i + 1]; + if (m > 256 * 16383) { + bottomt[i / 2] = 256 * 256; + bottomr[i / 2] = S[0] + 256 * S[1]; + S += 2; + M2[i / 2] = (((m + 255) >> 8) + 255) >> 8; + } else if (m >= 16384) { + bottomt[i / 2] = 256; + bottomr[i / 2] = S[0]; + S += 1; + M2[i / 2] = (m + 255) >> 8; + } else { + bottomt[i / 2] = 1; + bottomr[i / 2] = 0; + M2[i / 2] = m; + } + } + if (i < len) M2[i / 2] = M[i]; + Decode(R2, S, M2, (len + 1) / 2); + for (i = 0; i < len - 1; i += 2) { + uint32_t r1, r = bottomr[i / 2]; + uint16_t r0; + r += bottomt[i / 2] * R2[i / 2]; + uint32_divmod_uint14(&r1, &r0, r, M[i]); + r1 = uint32_mod_uint14(r1, M[i + 1]); + *out++ = r0; + *out++ = r1; + } + if (i < len) *out++ = R2[i / 2]; + } } -#define XDecrypt Decrypt - -#endif +static void R3_fromRq(small *out, const Fq *r) { + int i; + for (i = 0; i < p; ++i) out[i] = F3_freeze(r[i]); +} -/* ----- encoding small polynomials (including short polynomials) */ +static void R3_mult(small *h, const small *f, const small *g) { + int16_t fg[p + p - 1]; + int i, j; + for (i = 0; i < p + p - 1; ++i) fg[i] = 0; + for (i = 0; i < p; ++i) + for (j = 0; j < p; ++j) fg[i + j] += f[i] * (int16_t)g[j]; + for (i = p; i < p + p - 1; ++i) fg[i - p] += fg[i]; + for (i = p; i < p + p - 1; ++i) fg[i - p + 1] += fg[i]; + for (i = 0; i < p; ++i) h[i] = F3_freeze(fg[i]); +} -#define Small_bytes ((p+3)/4) +static int R3_recip(small *out, const small *in) { + small f[p + 1], g[p + 1], v[p + 1], r[p + 1]; + int sign, swap, t, i, loop, delta = 1; + for (i = 0; i < p + 1; ++i) v[i] = 0; + for (i = 0; i < p + 1; ++i) r[i] = 0; + r[0] = 1; + for (i = 0; i < p; ++i) f[i] = 0; + f[0] = 1; + f[p - 1] = f[p] = -1; + for (i = 0; i < p; ++i) g[p - 1 - i] = in[i]; + g[p] = 0; + for (loop = 0; loop < 2 * p - 1; ++loop) { + for (i = p; i > 0; --i) v[i] = v[i - 1]; + v[0] = 0; + sign = -g[0] * f[0]; + swap = crypto_int16_negative_mask(-delta) & crypto_int16_nonzero_mask(g[0]); + delta ^= swap & (delta ^ -delta); + delta += 1; + for (i = 0; i < p + 1; ++i) { + t = swap & (f[i] ^ g[i]); + f[i] ^= t; + g[i] ^= t; + t = swap & (v[i] ^ r[i]); + v[i] ^= t; + r[i] ^= t; + } + for (i = 0; i < p + 1; ++i) g[i] = F3_freeze(g[i] + sign * f[i]); + for (i = 0; i < p + 1; ++i) r[i] = F3_freeze(r[i] + sign * v[i]); + for (i = 0; i < p; ++i) g[i] = g[i + 1]; + g[p] = 0; + } + sign = f[0]; + for (i = 0; i < p; ++i) out[i] = sign * v[p - 1 - i]; + return crypto_int16_nonzero_mask(delta); +} -/* these are the only functions that rely on p mod 4 = 1 */ +static void Rq_mult_small(Fq *h, const Fq *f, const small *g) { + int32_t fg[p + p - 1]; + int i, j; + for (i = 0; i < p + p - 1; ++i) fg[i] = 0; + for (i = 0; i < p; ++i) + for (j = 0; j < p; ++j) fg[i + j] += f[i] * (int32_t)g[j]; + for (i = p; i < p + p - 1; ++i) fg[i - p] += fg[i]; + for (i = p; i < p + p - 1; ++i) fg[i - p + 1] += fg[i]; + for (i = 0; i < p; ++i) h[i] = Fq_freeze(fg[i]); +} -static void Small_encode(unsigned char *s,const small *f) -{ - small x; +static void Rq_mult3(Fq *h, const Fq *f) { int i; + for (i = 0; i < p; ++i) h[i] = Fq_freeze(3 * f[i]); +} - for (i = 0;i < p/4;++i) { - x = *f++ + 1; - x += (*f++ + 1)<<2; - x += (*f++ + 1)<<4; - x += (*f++ + 1)<<6; - *s++ = x; +static Fq Fq_recip(Fq a1) { + int i = 1; + Fq ai = a1; + while (i < q - 2) { + ai = Fq_freeze(a1 * (int32_t)ai); + i += 1; } - x = *f++ + 1; - *s++ = x; + return ai; } -static void Small_decode(small *f,const unsigned char *s) -{ - unsigned char x; - int i; - - for (i = 0;i < p/4;++i) { - x = *s++; - *f++ = ((small)(x&3))-1; x >>= 2; - *f++ = ((small)(x&3))-1; x >>= 2; - *f++ = ((small)(x&3))-1; x >>= 2; - *f++ = ((small)(x&3))-1; +static int Rq_recip3(Fq *out, const small *in) { + Fq f[p + 1], g[p + 1], v[p + 1], r[p + 1], scale; + int swap, t, i, loop, delta = 1; + int32_t f0, g0; + for (i = 0; i < p + 1; ++i) v[i] = 0; + for (i = 0; i < p + 1; ++i) r[i] = 0; + r[0] = Fq_recip(3); + for (i = 0; i < p; ++i) f[i] = 0; + f[0] = 1; + f[p - 1] = f[p] = -1; + for (i = 0; i < p; ++i) g[p - 1 - i] = in[i]; + g[p] = 0; + for (loop = 0; loop < 2 * p - 1; ++loop) { + for (i = p; i > 0; --i) v[i] = v[i - 1]; + v[0] = 0; + swap = crypto_int16_negative_mask(-delta) & crypto_int16_nonzero_mask(g[0]); + delta ^= swap & (delta ^ -delta); + delta += 1; + for (i = 0; i < p + 1; ++i) { + t = swap & (f[i] ^ g[i]); + f[i] ^= t; + g[i] ^= t; + t = swap & (v[i] ^ r[i]); + v[i] ^= t; + r[i] ^= t; + } + f0 = f[0]; + g0 = g[0]; + for (i = 0; i < p + 1; ++i) g[i] = Fq_freeze(f0 * g[i] - g0 * f[i]); + for (i = 0; i < p + 1; ++i) r[i] = Fq_freeze(f0 * r[i] - g0 * v[i]); + for (i = 0; i < p; ++i) g[i] = g[i + 1]; + g[p] = 0; } - x = *s++; - *f++ = ((small)(x&3))-1; + scale = Fq_recip(f[0]); + for (i = 0; i < p; ++i) out[i] = Fq_freeze(scale * (int32_t)v[p - 1 - i]); + return crypto_int16_nonzero_mask(delta); } -/* ----- encoding general polynomials */ - -#ifndef LPR - -static void Rq_encode(unsigned char *s,const Fq *r) -{ - uint16 R[p],M[p]; +static void Round(Fq *out, const Fq *a) { int i; - - for (i = 0;i < p;++i) R[i] = r[i]+q12; - for (i = 0;i < p;++i) M[i] = q; - Encode(s,R,M,p); + for (i = 0; i < p; ++i) out[i] = a[i] - F3_freeze(a[i]); } -static void Rq_decode(Fq *r,const unsigned char *s) -{ - uint16 R[p],M[p]; +static void Short_fromlist(small *out, const uint32_t *in) { + uint32_t L[p]; int i; - - for (i = 0;i < p;++i) M[i] = q; - Decode(R,s,M,p); - for (i = 0;i < p;++i) r[i] = ((Fq)R[i])-q12; + for (i = 0; i < w; ++i) L[i] = in[i] & (uint32_t)-2; + for (i = w; i < p; ++i) L[i] = (in[i] & (uint32_t)-3) | 1; + crypto_sort_uint32(L, p); + for (i = 0; i < p; ++i) out[i] = (L[i] & 3) - 1; } -#endif - -/* ----- encoding rounded polynomials */ - -static void Rounded_encode(unsigned char *s,const Fq *r) -{ - uint16 R[p],M[p]; +static void Hash_prefix(unsigned char *out, int b, const unsigned char *in, int inlen) { + unsigned char x[inlen + 1], h[64]; int i; - - for (i = 0;i < p;++i) R[i] = ((r[i]+q12)*10923)>>15; - for (i = 0;i < p;++i) M[i] = (q+2)/3; - Encode(s,R,M,p); + x[0] = b; + for (i = 0; i < inlen; ++i) x[i + 1] = in[i]; + crypto_hash_sha512(h, x, inlen + 1); + for (i = 0; i < 32; ++i) out[i] = h[i]; } -static void Rounded_decode(Fq *r,const unsigned char *s) -{ - uint16 R[p],M[p]; +static uint32_t urandom32(void) { + unsigned char c[4]; + uint32_t result = 0; int i; - - for (i = 0;i < p;++i) M[i] = (q+2)/3; - Decode(R,s,M,p); - for (i = 0;i < p;++i) r[i] = R[i]*3-q12; + randombytes(c, 4); + for (i = 0; i < 4; ++i) result += ((uint32_t)c[i]) << (8 * i); + return result; } -/* ----- encoding top polynomials */ - -#ifdef LPR - -#define Top_bytes (I/2) - -static void Top_encode(unsigned char *s,const int8 *T) -{ +static void Short_random(small *out) { + uint32_t L[p]; int i; - for (i = 0;i < Top_bytes;++i) - s[i] = T[2*i]+(T[2*i+1]<<4); + for (i = 0; i < p; ++i) L[i] = urandom32(); + Short_fromlist(out, L); } -static void Top_decode(int8 *T,const unsigned char *s) -{ +static void Small_random(small *out) { int i; - for (i = 0;i < Top_bytes;++i) { - T[2*i] = s[i]&15; - T[2*i+1] = s[i]>>4; - } + for (i = 0; i < p; ++i) out[i] = (((urandom32() & 0x3fffffff) * 3) >> 30) - 1; } -#endif - -/* ----- Streamlined NTRU Prime Core plus encoding */ - -#ifndef LPR - -typedef small Inputs[p]; /* passed by reference */ -#define Inputs_random Short_random -#define Inputs_encode Small_encode -#define Inputs_bytes Small_bytes - -#define Ciphertexts_bytes Rounded_bytes -#define SecretKeys_bytes (2*Small_bytes) -#define PublicKeys_bytes Rq_bytes - -/* pk,sk = ZKeyGen() */ -static void ZKeyGen(unsigned char *pk,unsigned char *sk) -{ - Fq h[p]; - small f[p],v[p]; - - KeyGen(h,f,v); - Rq_encode(pk,h); - Small_encode(sk,f); sk += Small_bytes; - Small_encode(sk,v); +static void KeyGen(Fq *h, small *f, small *ginv) { + small g[p]; + Fq finv[p]; + for (;;) { + int result; + Small_random(g); + result = R3_recip(ginv, g); + crypto_declassify(&result, sizeof result); + if (result == 0) break; + } + Short_random(f); + Rq_recip3(finv, f); + Rq_mult_small(h, finv, g); } -/* C = ZEncrypt(r,pk) */ -static void ZEncrypt(unsigned char *C,const Inputs r,const unsigned char *pk) -{ - Fq h[p]; - Fq c[p]; - Rq_decode(h,pk); - Encrypt(c,r,h); - Rounded_encode(C,c); +static void Encrypt(Fq *c, const small *r, const Fq *h) { + Fq hr[p]; + Rq_mult_small(hr, h, r); + Round(c, hr); +} + +static void Decrypt(small *r, const Fq *c, const small *f, const small *ginv) { + Fq cf[p], cf3[p]; + small e[p], ev[p]; + int mask, i; + Rq_mult_small(cf, c, f); + Rq_mult3(cf3, cf); + R3_fromRq(e, cf3); + R3_mult(ev, e, ginv); + mask = Weightw_mask(ev); + for (i = 0; i < w; ++i) r[i] = ((ev[i] ^ 1) & ~mask) ^ 1; + for (i = w; i < p; ++i) r[i] = ev[i] & ~mask; +} + +static void Small_encode(unsigned char *s, const small *f) { + int i, j; + for (i = 0; i < p / 4; ++i) { + small x = 0; + for (j = 0;j < 4;++j) x += (*f++ + 1) << (2 * j); + *s++ = x; + } + *s = *f++ + 1; } -/* r = ZDecrypt(C,sk) */ -static void ZDecrypt(Inputs r,const unsigned char *C,const unsigned char *sk) -{ - small f[p],v[p]; - Fq c[p]; - - Small_decode(f,sk); sk += Small_bytes; - Small_decode(v,sk); - Rounded_decode(c,C); - Decrypt(r,c,f,v); +static void Small_decode(small *f, const unsigned char *s) { + int i, j; + for (i = 0; i < p / 4; ++i) { + unsigned char x = *s++; + for (j = 0;j < 4;++j) *f++ = ((small)((x >> (2 * j)) & 3)) - 1; + } + *f++ = ((small)(*s & 3)) - 1; } -#endif - -/* ----- NTRU LPRime Expand plus encoding */ - -#ifdef LPR - -#define Ciphertexts_bytes (Rounded_bytes+Top_bytes) -#define SecretKeys_bytes Small_bytes -#define PublicKeys_bytes (Seeds_bytes+Rounded_bytes) - -static void Inputs_random(Inputs r) -{ - unsigned char s[Inputs_bytes]; +static void Rq_encode(unsigned char *s, const Fq *r) { + uint16_t R[p], M[p]; int i; - - randombytes(s,sizeof s); - for (i = 0;i < I;++i) r[i] = 1&(s[i>>3]>>(i&7)); + for (i = 0; i < p; ++i) R[i] = r[i] + q12; + for (i = 0; i < p; ++i) M[i] = q; + Encode(s, R, M, p); } -/* pk,sk = ZKeyGen() */ -static void ZKeyGen(unsigned char *pk,unsigned char *sk) -{ - Fq A[p]; - small a[p]; - - XKeyGen(pk,A,a); pk += Seeds_bytes; - Rounded_encode(pk,A); - Small_encode(sk,a); -} - -/* c = ZEncrypt(r,pk) */ -static void ZEncrypt(unsigned char *c,const Inputs r,const unsigned char *pk) -{ - Fq A[p]; - Fq B[p]; - int8 T[I]; - - Rounded_decode(A,pk+Seeds_bytes); - XEncrypt(B,T,r,pk,A); - Rounded_encode(c,B); c += Rounded_bytes; - Top_encode(c,T); +static void Rq_decode(Fq *r, const unsigned char *s) { + uint16_t R[p], M[p]; + int i; + for (i = 0; i < p; ++i) M[i] = q; + Decode(R, s, M, p); + for (i = 0; i < p; ++i) r[i] = ((Fq)R[i]) - q12; } -/* r = ZDecrypt(C,sk) */ -static void ZDecrypt(Inputs r,const unsigned char *c,const unsigned char *sk) -{ - small a[p]; - Fq B[p]; - int8 T[I]; - - Small_decode(a,sk); - Rounded_decode(B,c); - Top_decode(T,c+Rounded_bytes); - XDecrypt(r,B,T,a); +static void Rounded_encode(unsigned char *s, const Fq *r) { + uint16_t R[p], M[p]; + int i; + for (i = 0; i < p; ++i) R[i] = ((r[i] + q12) * 10923) >> 15; + for (i = 0; i < p; ++i) M[i] = (q + 2) / 3; + Encode(s, R, M, p); } -#endif - -/* ----- confirmation hash */ - -#define Confirm_bytes 32 - -/* h = HashConfirm(r,pk,cache); cache is Hash4(pk) */ -static void HashConfirm(unsigned char *h,const unsigned char *r,const unsigned char *pk,const unsigned char *cache) -{ -#ifndef LPR - unsigned char x[Hash_bytes*2]; +static void Rounded_decode(Fq *r, const unsigned char *s) { + uint16_t R[p], M[p]; int i; + for (i = 0; i < p; ++i) M[i] = (q + 2) / 3; + Decode(R, s, M, p); + for (i = 0; i < p; ++i) r[i] = R[i] * 3 - q12; +} - Hash_prefix(x,3,r,Inputs_bytes); - for (i = 0;i < Hash_bytes;++i) x[Hash_bytes+i] = cache[i]; -#else - unsigned char x[Inputs_bytes+Hash_bytes]; - int i; +static void ZKeyGen(unsigned char *pk, unsigned char *sk) { + Fq h[p]; + small f[p], v[p]; + KeyGen(h, f, v); + Rq_encode(pk, h); + Small_encode(sk, f); + Small_encode(sk + Small_bytes, v); +} - for (i = 0;i < Inputs_bytes;++i) x[i] = r[i]; - for (i = 0;i < Hash_bytes;++i) x[Inputs_bytes+i] = cache[i]; -#endif - Hash_prefix(h,2,x,sizeof x); +static void ZEncrypt(unsigned char *C, const Inputs r, const unsigned char *pk) { + Fq h[p], c[p]; + Rq_decode(h, pk); + Encrypt(c, r, h); + Rounded_encode(C, c); } -/* ----- session-key hash */ +static void ZDecrypt(Inputs r, const unsigned char *C, const unsigned char *sk) { + small f[p], v[p]; + Fq c[p]; + Small_decode(f, sk); + Small_decode(v, sk + Small_bytes); + Rounded_decode(c, C); + Decrypt(r, c, f, v); +} -/* k = HashSession(b,y,z) */ -static void HashSession(unsigned char *k,int b,const unsigned char *y,const unsigned char *z) -{ -#ifndef LPR - unsigned char x[Hash_bytes+Ciphertexts_bytes+Confirm_bytes]; +static void HashConfirm(unsigned char *h, const unsigned char *r, const unsigned char *cache) { + unsigned char x[Hash_bytes * 2]; int i; + Hash_prefix(x, 3, r, Small_bytes); + for (i = 0; i < Hash_bytes; ++i) x[Hash_bytes + i] = cache[i]; + Hash_prefix(h, 2, x, sizeof x); +} - Hash_prefix(x,3,y,Inputs_bytes); - for (i = 0;i < Ciphertexts_bytes+Confirm_bytes;++i) x[Hash_bytes+i] = z[i]; -#else - unsigned char x[Inputs_bytes+Ciphertexts_bytes+Confirm_bytes]; +static void HashSession(unsigned char *k, int b, const unsigned char *y, const unsigned char *z) { + unsigned char x[Hash_bytes + crypto_kem_sntrup761_CIPHERTEXTBYTES]; int i; - - for (i = 0;i < Inputs_bytes;++i) x[i] = y[i]; - for (i = 0;i < Ciphertexts_bytes+Confirm_bytes;++i) x[Inputs_bytes+i] = z[i]; -#endif - Hash_prefix(k,b,x,sizeof x); + Hash_prefix(x, 3, y, Small_bytes); + for (i = 0; i < crypto_kem_sntrup761_CIPHERTEXTBYTES; ++i) x[Hash_bytes + i] = z[i]; + Hash_prefix(k, b, x, sizeof x); } -/* ----- Streamlined NTRU Prime and NTRU LPRime */ - -/* pk,sk = KEM_KeyGen() */ -static void KEM_KeyGen(unsigned char *pk,unsigned char *sk) -{ +int crypto_kem_sntrup761_keypair(unsigned char *pk, unsigned char *sk) { int i; - - ZKeyGen(pk,sk); sk += SecretKeys_bytes; - for (i = 0;i < PublicKeys_bytes;++i) *sk++ = pk[i]; - randombytes(sk,Inputs_bytes); sk += Inputs_bytes; - Hash_prefix(sk,4,pk,PublicKeys_bytes); + ZKeyGen(pk, sk); + sk += SecretKeys_bytes; + for (i = 0; i < crypto_kem_sntrup761_PUBLICKEYBYTES; ++i) *sk++ = pk[i]; + randombytes(sk, Small_bytes); + Hash_prefix(sk + Small_bytes, 4, pk, crypto_kem_sntrup761_PUBLICKEYBYTES); + return 0; } -/* c,r_enc = Hide(r,pk,cache); cache is Hash4(pk) */ -static void Hide(unsigned char *c,unsigned char *r_enc,const Inputs r,const unsigned char *pk,const unsigned char *cache) -{ - Inputs_encode(r_enc,r); - ZEncrypt(c,r,pk); c += Ciphertexts_bytes; - HashConfirm(c,r_enc,pk,cache); +static void Hide(unsigned char *c, unsigned char *r_enc, const Inputs r, const unsigned char *pk, const unsigned char *cache) { + Small_encode(r_enc, r); + ZEncrypt(c, r, pk); + HashConfirm(c + crypto_kem_sntrup761_CIPHERTEXTBYTES - Confirm_bytes, r_enc, cache); } -/* c,k = Encap(pk) */ -static void Encap(unsigned char *c,unsigned char *k,const unsigned char *pk) -{ +int crypto_kem_sntrup761_enc(unsigned char *c, unsigned char *k, const unsigned char *pk) { Inputs r; - unsigned char r_enc[Inputs_bytes]; - unsigned char cache[Hash_bytes]; - - Hash_prefix(cache,4,pk,PublicKeys_bytes); - Inputs_random(r); - Hide(c,r_enc,r,pk,cache); - HashSession(k,1,r_enc,c); + unsigned char r_enc[Small_bytes], cache[Hash_bytes]; + Hash_prefix(cache, 4, pk, crypto_kem_sntrup761_PUBLICKEYBYTES); + Short_random(r); + Hide(c, r_enc, r, pk, cache); + HashSession(k, 1, r_enc, c); + return 0; } -/* 0 if matching ciphertext+confirm, else -1 */ -static int Ciphertexts_diff_mask(const unsigned char *c,const unsigned char *c2) -{ - uint16 differentbits = 0; - int len = Ciphertexts_bytes+Confirm_bytes; - - while (len-- > 0) differentbits |= (*c++)^(*c2++); - return (1&((differentbits-1)>>8))-1; +static int Ciphertexts_diff_mask(const unsigned char *c, const unsigned char *c2) { + uint16_t differentbits = 0; + int len = crypto_kem_sntrup761_CIPHERTEXTBYTES; + while (len-- > 0) differentbits |= (*c++) ^ (*c2++); + return (crypto_int64_bitmod_01((differentbits - 1),8)) - 1; } -/* k = Decap(c,sk) */ -static void Decap(unsigned char *k,const unsigned char *c,const unsigned char *sk) -{ +int crypto_kem_sntrup761_dec(unsigned char *k, const unsigned char *c, const unsigned char *sk) { const unsigned char *pk = sk + SecretKeys_bytes; - const unsigned char *rho = pk + PublicKeys_bytes; - const unsigned char *cache = rho + Inputs_bytes; + const unsigned char *rho = pk + crypto_kem_sntrup761_PUBLICKEYBYTES; + const unsigned char *cache = rho + Small_bytes; Inputs r; - unsigned char r_enc[Inputs_bytes]; - unsigned char cnew[Ciphertexts_bytes+Confirm_bytes]; - int mask; - int i; - - ZDecrypt(r,c,sk); - Hide(cnew,r_enc,r,pk,cache); - mask = Ciphertexts_diff_mask(c,cnew); - for (i = 0;i < Inputs_bytes;++i) r_enc[i] ^= mask&(r_enc[i]^rho[i]); - HashSession(k,1+mask,r_enc,c); -} - -/* ----- crypto_kem API */ - - -int crypto_kem_sntrup761_keypair(unsigned char *pk,unsigned char *sk) -{ - KEM_KeyGen(pk,sk); + unsigned char r_enc[Small_bytes], cnew[crypto_kem_sntrup761_CIPHERTEXTBYTES]; + int mask, i; + ZDecrypt(r, c, sk); + Hide(cnew, r_enc, r, pk, cache); + mask = Ciphertexts_diff_mask(c, cnew); + for (i = 0; i < Small_bytes; ++i) r_enc[i] ^= mask & (r_enc[i] ^ rho[i]); + HashSession(k, 1 + mask, r_enc, c); return 0; } -int crypto_kem_sntrup761_enc(unsigned char *c,unsigned char *k,const unsigned char *pk) -{ - Encap(c,k,pk); - return 0; -} - -int crypto_kem_sntrup761_dec(unsigned char *k,const unsigned char *c,const unsigned char *sk) -{ - Decap(k,c,sk); - return 0; -} #endif /* USE_SNTRUP761X25519 */ diff --git a/sntrup761.sh b/sntrup761.sh index db4e9aed08a..4de8dc33479 100644 --- a/sntrup761.sh +++ b/sntrup761.sh @@ -1,25 +1,18 @@ #!/bin/sh -# $OpenBSD: sntrup761.sh,v 1.7 2023/01/11 02:13:52 djm Exp $ +# $OpenBSD: sntrup761.sh,v 1.9 2024/09/16 05:37:05 djm Exp $ # Placed in the Public Domain. # -AUTHOR="supercop-20201130/crypto_kem/sntrup761/ref/implementors" -FILES=" - supercop-20201130/crypto_sort/int32/portable4/int32_minmax.inc - supercop-20201130/crypto_sort/int32/portable4/sort.c - supercop-20201130/crypto_sort/uint32/useint32/sort.c - supercop-20201130/crypto_kem/sntrup761/ref/uint32.c - supercop-20201130/crypto_kem/sntrup761/ref/int32.c - supercop-20201130/crypto_kem/sntrup761/ref/paramsmenu.h - supercop-20201130/crypto_kem/sntrup761/ref/params.h - supercop-20201130/crypto_kem/sntrup761/ref/Decode.h - supercop-20201130/crypto_kem/sntrup761/ref/Decode.c - supercop-20201130/crypto_kem/sntrup761/ref/Encode.h - supercop-20201130/crypto_kem/sntrup761/ref/Encode.c - supercop-20201130/crypto_kem/sntrup761/ref/kem.c +AUTHOR="supercop-20240808/crypto_kem/sntrup761/ref/implementors" +FILES=" supercop-20240808/cryptoint/crypto_int16.h + supercop-20240808/cryptoint/crypto_int32.h + supercop-20240808/cryptoint/crypto_int64.h + supercop-20240808/crypto_sort/int32/portable4/sort.c + supercop-20240808/crypto_sort/uint32/useint32/sort.c + supercop-20240808/crypto_kem/sntrup761/compact/kem.c " ### -set -e +set -euo pipefail cd $1 echo -n '/* $' echo 'OpenBSD: $ */' @@ -32,12 +25,19 @@ echo echo '#include ' echo '#include "crypto_api.h"' echo +echo '#define crypto_declassify(x, y) do {} while (0)' +echo # Map the types used in this code to the ones in crypto_api.h. We use #define # instead of typedef since some systems have existing intXX types and do not # permit multiple typedefs even if they do not conflict. for t in int8 uint8 int16 uint16 int32 uint32 int64 uint64; do echo "#define $t crypto_${t}" done + +for x in 16 32 64 ; do + echo "extern volatile crypto_int$x crypto_int${x}_optblocker;" +done + echo for i in $FILES; do echo "/* from $i */" @@ -57,14 +57,32 @@ for i in $FILES; do -e 's/[ ]*$//' \ $i | \ case "$i" in - # Use int64_t for intermediate values in int32_MINMAX to prevent signed - # 32-bit integer overflow when called by crypto_sort_uint32. - */int32_minmax.inc) - sed -e "s/int32 ab = b ^ a/int64_t ab = (int64_t)b ^ (int64_t)a/" \ - -e "s/int32 c = b - a/int64_t c = (int64_t)b - (int64_t)a/" + */cryptoint/crypto_int16.h) + sed -e "s/static void crypto_int16_store/void crypto_int16_store/" \ + -e "s/^[#]define crypto_int16_optblocker.*//" \ + -e "s/static void crypto_int16_minmax/void crypto_int16_minmax/" + ;; + */cryptoint/crypto_int32.h) + # Use int64_t for intermediate values in crypto_int32_minmax to + # prevent signed 32-bit integer overflow when called by + # crypto_sort_int32. Original code depends on -fwrapv (we set -ftrapv) + sed -e "s/static void crypto_int32_store/void crypto_int32_store/" \ + -e "s/^[#]define crypto_int32_optblocker.*//" \ + -e "s/crypto_int32 crypto_int32_r = crypto_int32_y ^ crypto_int32_x;/crypto_int64 crypto_int32_r = (crypto_int64)crypto_int32_y ^ (crypto_int64)crypto_int32_x;/" \ + -e "s/crypto_int32 crypto_int32_z = crypto_int32_y - crypto_int32_x;/crypto_int64 crypto_int32_z = (crypto_int64)crypto_int32_y - (crypto_int64)crypto_int32_x;/" \ + -e "s/static void crypto_int32_minmax/void crypto_int32_minmax/" + ;; + */cryptoint/crypto_int64.h) + sed -e "s/static void crypto_int64_store/void crypto_int64_store/" \ + -e "s/^[#]define crypto_int64_optblocker.*//" \ + -e "s/static void crypto_int64_minmax/void crypto_int64_minmax/" ;; */int32/portable4/sort.c) - sed -e "s/void crypto_sort/void crypto_sort_int32/g" + sed -e "s/void crypto_sort[(]/void crypto_sort_int32(/g" + ;; + */int32/portable5/sort.c) + sed -e "s/crypto_sort_smallindices/crypto_sort_int32_smallindices/"\ + -e "s/void crypto_sort[(]/void crypto_sort_int32(/g" ;; */uint32/useint32/sort.c) sed -e "s/void crypto_sort/void crypto_sort_uint32/g" diff --git a/srclimit.c b/srclimit.c index 3dbdbf67526..c63a462e278 100644 --- a/srclimit.c +++ b/srclimit.c @@ -381,8 +381,12 @@ srclimit_penalise(struct xaddr *addr, int penalty_type) penalty_secs = penalty_cfg.penalty_noauth; reason = "penalty: connections without attempting authentication"; break; + case SRCLIMIT_PENALTY_REFUSECONNECTION: + penalty_secs = penalty_cfg.penalty_refuseconnection; + reason = "penalty: connection prohibited by RefuseConnection"; + break; case SRCLIMIT_PENALTY_GRACE_EXCEEDED: - penalty_secs = penalty_cfg.penalty_crash; + penalty_secs = penalty_cfg.penalty_grace; reason = "penalty: exceeded LoginGraceTime"; break; default: diff --git a/srclimit.h b/srclimit.h index 74a6f2b836d..77d951ba66e 100644 --- a/srclimit.h +++ b/srclimit.h @@ -22,16 +22,18 @@ void srclimit_init(int, int, int, int, int srclimit_check_allow(int, int); void srclimit_done(int); -#define SRCLIMIT_PENALTY_NONE 0 -#define SRCLIMIT_PENALTY_CRASH 1 -#define SRCLIMIT_PENALTY_AUTHFAIL 2 -#define SRCLIMIT_PENALTY_GRACE_EXCEEDED 3 -#define SRCLIMIT_PENALTY_NOAUTH 4 +#define SRCLIMIT_PENALTY_NONE 0 +#define SRCLIMIT_PENALTY_CRASH 1 +#define SRCLIMIT_PENALTY_AUTHFAIL 2 +#define SRCLIMIT_PENALTY_GRACE_EXCEEDED 3 +#define SRCLIMIT_PENALTY_NOAUTH 4 +#define SRCLIMIT_PENALTY_REFUSECONNECTION 5 /* meaningful exit values, used by sshd listener for penalties */ #define EXIT_LOGIN_GRACE 3 /* login grace period exceeded */ #define EXIT_CHILD_CRASH 4 /* preauth child crashed */ #define EXIT_AUTH_ATTEMPTED 5 /* at least one auth attempt made */ +#define EXIT_CONFIG_REFUSED 6 /* sshd_config RefuseConnection */ void srclimit_penalise(struct xaddr *, int); int srclimit_penalty_check_allow(int, const char **); diff --git a/ssh-add.0 b/ssh-add.0 index 30eed6672d6..af9901186c7 100644 --- a/ssh-add.0 +++ b/ssh-add.0 @@ -206,4 +206,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.5 June 17, 2024 OpenBSD 7.5 +OpenBSD 7.6 June 17, 2024 OpenBSD 7.6 diff --git a/ssh-add.c b/ssh-add.c index fd0c39d74d7..b90ae87b845 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-add.c,v 1.172 2024/01/11 01:45:36 djm Exp $ */ +/* $OpenBSD: ssh-add.c,v 1.173 2024/09/06 02:30:44 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -701,7 +701,7 @@ parse_dest_constraint_hop(const char *s, struct dest_constraint_hop *dch, memset(dch, '\0', sizeof(*dch)); os = xstrdup(s); - if ((host = strchr(os, '@')) == NULL) + if ((host = strrchr(os, '@')) == NULL) host = os; else { *host++ = '\0'; diff --git a/ssh-agent.0 b/ssh-agent.0 index 2e4ef7b6e38..03006198f77 100644 --- a/ssh-agent.0 +++ b/ssh-agent.0 @@ -22,8 +22,8 @@ DESCRIPTION Bind the agent to the UNIX-domain socket bind_address. The default is $TMPDIR/ssh-XXXXXXXXXX/agent.. - -c Generate C-shell commands on stdout. This is the default if - SHELL looks like it's a csh style of shell. + -c Generate C-shell commands on standard output. This is the + default if SHELL looks like it's a csh style of shell. -D Foreground mode. When this option is specified, ssh-agent will not fork. @@ -40,8 +40,8 @@ DESCRIPTION variable). -O option - Specify an option when starting ssh-agent. Currently two options - are supported: allow-remote-pkcs11 and no-restrict-websafe. + Specify an option when starting ssh-agent. The supported options + are: allow-remote-pkcs11, no-restrict-websafe and websafe-allow. The allow-remote-pkcs11 option allows clients of a forwarded ssh-agent to load PKCS#11 or FIDO provider libraries. By default @@ -60,16 +60,26 @@ DESCRIPTION from also implicitly forwarding the ability to authenticate to websites. + Alternately the websafe-allow option allows specifying a pattern- + list of key application strings to replace the default + application allow-list, for example: + M-bM-^@M-^\websafe-allow=ssh:*,example.org,*.example.comM-bM-^@M-^] + + See PATTERNS in ssh_config(5) for a description of pattern-list + syntax. + -P allowed_providers Specify a pattern-list of acceptable paths for PKCS#11 provider and FIDO authenticator middleware shared libraries that may be used with the -S or -s options to ssh-add(1). Libraries that do - not match the pattern list will be refused. See PATTERNS in - ssh_config(5) for a description of pattern-list syntax. The - default list is M-bM-^@M-^\usr/lib*/*,/usr/local/lib*/*M-bM-^@M-^]. + not match the pattern list will be refused. The default list is + M-bM-^@M-^\usr/lib*/*,/usr/local/lib*/*M-bM-^@M-^]. + + See PATTERNS in ssh_config(5) for a description of pattern-list + syntax. - -s Generate Bourne shell commands on stdout. This is the default if - SHELL does not look like it's a csh style of shell. + -s Generate Bourne shell commands on standard output. This is the + default if SHELL does not look like it's a csh style of shell. -t life Set a default value for the maximum lifetime of identities added @@ -83,7 +93,7 @@ DESCRIPTION as a subprocess of the agent. The agent exits automatically when the command given on the command line terminates. - There are two main ways to get an agent set up. The first is at the + There are three main ways to get an agent set up. The first is at the start of an X session, where all other windows or programs are started as children of the ssh-agent program. The agent starts a command under which its environment variables are exported, for example ssh-agent xterm @@ -94,8 +104,18 @@ DESCRIPTION variables, which in turn can be evaluated in the calling shell, for example eval `ssh-agent -s`. - In both cases, ssh(1) looks at these environment variables and uses them - to establish a connection to the agent. + In both of these cases, ssh(1) looks at these environment variables and + uses them to establish a connection to the agent. + + The third way to run ssh-agent is via socket activation from a + supervising process, such as systemd. In this mode, the supervising + process creates the listening socket and is responsible for starting + ssh-agent as needed, and also for communicating the location of the + socket listener to other programs in the user's session. Socket + activation is used when ssh-agent is started with either of the -d or -D + flags, no socket listening address specified by the -a flag, and both the + LISTEN_FDS and LISTEN_PID environment variables correctly supplied by the + supervising process. The agent initially does not have any private keys. Keys are added using ssh-add(1) or by ssh(1) when AddKeysToAgent is set in ssh_config(5). @@ -111,6 +131,8 @@ DESCRIPTION the result is returned to the requester, allowing the user access to their identities anywhere in the network in a secure fashion. + ssh-agent will delete all keys it has loaded upon receiving SIGUSR1. + ENVIRONMENT SSH_AGENT_PID When ssh-agent starts, it stores the name of the agent's process ID (PID) in this variable. @@ -137,4 +159,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.5 August 10, 2023 OpenBSD 7.5 +OpenBSD 7.6 February 9, 2025 OpenBSD 7.6 diff --git a/ssh-agent.1 b/ssh-agent.1 index 0b93d03a3d2..533ad6d3a6d 100644 --- a/ssh-agent.1 +++ b/ssh-agent.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-agent.1,v 1.79 2023/08/10 14:37:32 naddy Exp $ +.\" $OpenBSD: ssh-agent.1,v 1.82 2025/02/09 18:24:08 schwarze Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -34,7 +34,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 10 2023 $ +.Dd $Mdocdate: February 9 2025 $ .Dt SSH-AGENT 1 .Os .Sh NAME @@ -77,8 +77,7 @@ socket The default is .Pa $TMPDIR/ssh-XXXXXXXXXX/agent.\*(Ltppid\*(Gt . .It Fl c -Generate C-shell commands on -.Dv stdout . +Generate C-shell commands on standard output. This is the default if .Ev SHELL looks like it's a csh style of shell. @@ -107,10 +106,11 @@ environment variable). .It Fl O Ar option Specify an option when starting .Nm . -Currently two options are supported: -.Cm allow-remote-pkcs11 +The supported options are: +.Cm allow-remote-pkcs11 , +.Cm no-restrict-websafe and -.Cm no-restrict-websafe . +.Cm websafe-allow . .Pp The .Cm allow-remote-pkcs11 @@ -143,6 +143,16 @@ user authentication request or a signature. The default behaviour prevents forwarded access to a FIDO key from also implicitly forwarding the ability to authenticate to websites. +.Pp +Alternately the +.Cm websafe-allow +option allows specifying a pattern-list of key application strings to +replace the default application allow-list, for example: +.Dq websafe-allow=ssh:*,example.org,*.example.com +.Pp +See PATTERNS in +.Xr ssh_config 5 +for a description of pattern-list syntax. .It Fl P Ar allowed_providers Specify a pattern-list of acceptable paths for PKCS#11 provider and FIDO authenticator middleware shared libraries that may be used with the @@ -152,14 +162,14 @@ or options to .Xr ssh-add 1 . Libraries that do not match the pattern list will be refused. +The default list is +.Dq usr/lib*/*,/usr/local/lib*/* . +.Pp See PATTERNS in .Xr ssh_config 5 for a description of pattern-list syntax. -The default list is -.Dq usr/lib*/*,/usr/local/lib*/* . .It Fl s -Generate Bourne shell commands on -.Dv stdout . +Generate Bourne shell commands on standard output. This is the default if .Ev SHELL does not look like it's a csh style of shell. @@ -178,7 +188,7 @@ The agent exits automatically when the command given on the command line terminates. .El .Pp -There are two main ways to get an agent set up. +There are three main ways to get an agent set up. The first is at the start of an X session, where all other windows or programs are started as children of the .Nm @@ -196,11 +206,33 @@ it prints the shell commands required to set its environment variables, which in turn can be evaluated in the calling shell, for example .Cm eval `ssh-agent -s` . .Pp -In both cases, +In both of these cases, .Xr ssh 1 looks at these environment variables and uses them to establish a connection to the agent. .Pp +The third way to run +.Nm +is via socket activation from a supervising process, such as systemd. +In this mode, the supervising process creates the listening socket and +is responsible for starting +.Nm +as needed, and also for communicating the location of the socket listener +to other programs in the user's session. +Socket activation is used when +.Nm +is started with either of the +.Fl d +or +.Fl D +flags, no socket listening address specified by the +.Fl a +flag, and both the +.Ev LISTEN_FDS +and +.Ev LISTEN_PID +environment variables correctly supplied by the supervising process. +.Pp The agent initially does not have any private keys. Keys are added using .Xr ssh-add 1 @@ -233,6 +265,10 @@ the connection to the agent is forwarded over SSH remote connections and the result is returned to the requester, allowing the user access to their identities anywhere in the network in a secure fashion. +.Pp +.Nm +will delete all keys it has loaded upon receiving +.Dv SIGUSR1 . .Sh ENVIRONMENT .Bl -tag -width "SSH_AGENT_PID" .It Ev SSH_AGENT_PID diff --git a/ssh-agent.c b/ssh-agent.c index d16fd6c3e4d..c27c5a956f2 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -94,6 +94,9 @@ #ifndef DEFAULT_ALLOWED_PROVIDERS # define DEFAULT_ALLOWED_PROVIDERS "/usr/lib*/*,/usr/local/lib*/*" #endif +#ifndef DEFAULT_WEBSAFE_ALLOWLIST +# define DEFAULT_WEBSAFE_ALLOWLIST "ssh:*" +#endif /* Maximum accepted message length */ #define AGENT_MAX_LEN (256*1024) @@ -162,7 +165,8 @@ int max_fd = 0; pid_t parent_pid = -1; time_t parent_alive_interval = 0; -sig_atomic_t signalled = 0; +static sig_atomic_t signalled_exit; +static sig_atomic_t signalled_keydrop; /* pid of process for which cleanup_socket is applicable */ pid_t cleanup_pid = 0; @@ -197,6 +201,7 @@ static int fingerprint_hash = SSH_FP_HASH_DEFAULT; /* Refuse signing of non-SSH messages for web-origin FIDO keys */ static int restrict_websafe = 1; +static char *websafe_allowlist; static void close_socket(SocketEntry *e) @@ -924,7 +929,8 @@ process_sign_request2(SocketEntry *e) } if (sshkey_is_sk(id->key)) { if (restrict_websafe && - strncmp(id->key->sk_application, "ssh:", 4) != 0 && + match_pattern_list(id->key->sk_application, + websafe_allowlist, 0) != 1 && !check_websafe_message_contents(key, data)) { /* error already logged */ goto send; @@ -1021,7 +1027,7 @@ process_remove_identity(SocketEntry *e) } static void -process_remove_all_identities(SocketEntry *e) +remove_all_identities(void) { Identity *id; @@ -1035,6 +1041,12 @@ process_remove_all_identities(SocketEntry *e) /* Mark that there are no identities. */ idtab->nentries = 0; +} + +static void +process_remove_all_identities(SocketEntry *e) +{ + remove_all_identities(); /* Send success. */ send_status(e, 1); @@ -1707,6 +1719,10 @@ process_ext_session_bind(SocketEntry *e) error_fr(r, "parse"); goto out; } + if (sshbuf_len(sid) > AGENT_MAX_SID_LEN) { + error_f("session ID too long"); + goto out; + } if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT, SSH_FP_DEFAULT)) == NULL) fatal_f("fingerprint failed"); @@ -2165,7 +2181,13 @@ cleanup_exit(int i) static void cleanup_handler(int sig) { - signalled = sig; + signalled_exit = sig; +} + +static void +keydrop_handler(int sig) +{ + signalled_keydrop = sig; } static void @@ -2198,8 +2220,10 @@ int main(int ac, char **av) { int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0; - int sock, ch, result, saved_errno; - char *shell, *format, *pidstr, *agentsocket = NULL; + int sock = -1, ch, result, saved_errno; + char *shell, *format, *fdstr, *pidstr, *agentsocket = NULL; + const char *errstr = NULL; + const char *ccp; #ifdef HAVE_SETRLIMIT struct rlimit rlim; #endif @@ -2252,7 +2276,12 @@ main(int ac, char **av) restrict_websafe = 0; else if (strcmp(optarg, "allow-remote-pkcs11") == 0) remote_add_provider = 1; - else + else if ((ccp = strprefix(optarg, + "websafe-allow=", 0)) != NULL) { + if (websafe_allowlist != NULL) + fatal("websafe-allow already set"); + websafe_allowlist = xstrdup(ccp); + } else fatal("Unknown -O option"); break; case 'P': @@ -2296,6 +2325,8 @@ main(int ac, char **av) if (allowed_providers == NULL) allowed_providers = xstrdup(DEFAULT_ALLOWED_PROVIDERS); + if (websafe_allowlist == NULL) + websafe_allowlist = xstrdup(DEFAULT_WEBSAFE_ALLOWLIST); if (ac == 0 && !c_flag && !s_flag) { shell = getenv("SHELL"); @@ -2304,8 +2335,6 @@ main(int ac, char **av) c_flag = 1; } if (k_flag) { - const char *errstr = NULL; - pidstr = getenv(SSH_AGENTPID_ENV_NAME); if (pidstr == NULL) { fprintf(stderr, "%s not set, cannot kill agent\n", @@ -2343,33 +2372,59 @@ main(int ac, char **av) parent_pid = getpid(); - if (agentsocket == NULL) { - /* Create private directory for agent socket */ - mktemp_proto(socket_dir, sizeof(socket_dir)); - if (mkdtemp(socket_dir) == NULL) { - perror("mkdtemp: private socket dir"); - exit(1); + /* Has the socket been provided via socket activation? */ + if (agentsocket == NULL && ac == 0 && (d_flag || D_flag) && + (pidstr = getenv("LISTEN_PID")) != NULL && + (fdstr = getenv("LISTEN_FDS")) != NULL) { + if (strcmp(fdstr, "1") != 0) { + fatal("unexpected LISTEN_FDS contents " + "(want: \"1\" got\"%s\"", fdstr); } - snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir, + if (fcntl(3, F_GETFL) == -1) + fatal("LISTEN_FDS set but fd 3 unavailable"); + pid = (int)strtonum(pidstr, 1, INT_MAX, &errstr); + if (errstr != NULL) + fatal("invalid LISTEN_PID: %s", errstr); + if (pid != getpid()) + fatal("bad LISTEN_PID: %d vs pid %d", pid, getpid()); + debug("using socket activation on fd=3"); + sock = 3; + } + + /* Otherwise, create private directory for agent socket */ + if (sock == -1) { + if (agentsocket == NULL) { + mktemp_proto(socket_dir, sizeof(socket_dir)); + if (mkdtemp(socket_dir) == NULL) { + perror("mkdtemp: private socket dir"); + exit(1); + } + snprintf(socket_name, sizeof socket_name, + "%s/agent.%ld", socket_dir, (long)parent_pid); - } else { - /* Try to use specified agent socket */ - socket_dir[0] = '\0'; - strlcpy(socket_name, agentsocket, sizeof socket_name); + } else { + /* Try to use specified agent socket */ + socket_dir[0] = '\0'; + strlcpy(socket_name, agentsocket, sizeof socket_name); + } } + closefrom(sock == -1 ? STDERR_FILENO + 1 : sock + 1); + /* * Create socket early so it will exist before command gets run from * the parent. */ - prev_mask = umask(0177); - sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0); - if (sock < 0) { - /* XXX - unix_listener() calls error() not perror() */ - *socket_name = '\0'; /* Don't unlink any existing file */ - cleanup_exit(1); + if (sock == -1) { + prev_mask = umask(0177); + sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0); + if (sock < 0) { + /* XXX - unix_listener() calls error() not perror() */ + *socket_name = '\0'; /* Don't unlink existing file */ + cleanup_exit(1); + } + umask(prev_mask); } - umask(prev_mask); /* * Fork, and have the parent execute the command, if any, or present @@ -2379,11 +2434,14 @@ main(int ac, char **av) log_init(__progname, d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 1); - format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; - printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, - SSH_AUTHSOCKET_ENV_NAME); - printf("echo Agent pid %ld;\n", (long)parent_pid); - fflush(stdout); + if (socket_name[0] != '\0') { + format = c_flag ? + "setenv %s %s;\n" : "%s=%s; export %s;\n"; + printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, + SSH_AUTHSOCKET_ENV_NAME); + printf("echo Agent pid %ld;\n", (long)parent_pid); + fflush(stdout); + } goto skip; } pid = fork(); @@ -2448,11 +2506,13 @@ main(int ac, char **av) ssh_signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN); ssh_signal(SIGHUP, cleanup_handler); ssh_signal(SIGTERM, cleanup_handler); + ssh_signal(SIGUSR1, keydrop_handler); sigemptyset(&nsigset); sigaddset(&nsigset, SIGINT); sigaddset(&nsigset, SIGHUP); sigaddset(&nsigset, SIGTERM); + sigaddset(&nsigset, SIGUSR1); if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1) fatal("%s: pledge: %s", __progname, strerror(errno)); @@ -2460,10 +2520,16 @@ main(int ac, char **av) while (1) { sigprocmask(SIG_BLOCK, &nsigset, &osigset); - if (signalled != 0) { - logit("exiting on signal %d", (int)signalled); + if (signalled_exit != 0) { + logit("exiting on signal %d", (int)signalled_exit); cleanup_exit(2); } + if (signalled_keydrop) { + logit("signal %d received; removing all keys", + signalled_keydrop); + remove_all_identities(); + signalled_keydrop = 0; + } ptimeout_init(&timeout); prepare_poll(&pfd, &npfd, &timeout, maxfds); result = ppoll(pfd, npfd, ptimeout_get_tsp(&timeout), &osigset); diff --git a/ssh-ecdsa-sk.c b/ssh-ecdsa-sk.c index 5dcd3c13d34..3588b11a4a8 100644 --- a/ssh-ecdsa-sk.c +++ b/ssh-ecdsa-sk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ecdsa-sk.c,v 1.18 2023/03/08 04:43:12 guenther Exp $ */ +/* $OpenBSD: ssh-ecdsa-sk.c,v 1.19 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -237,11 +237,13 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, struct sshkey_sig_details **detailsp) { ECDSA_SIG *esig = NULL; + EVP_MD_CTX *md_ctx = NULL; BIGNUM *sig_r = NULL, *sig_s = NULL; u_char sig_flags; - u_char msghash[32], apphash[32], sighash[32]; + u_char msghash[32], apphash[32]; u_int sig_counter; - int is_webauthn = 0, ret = SSH_ERR_INTERNAL_ERROR; + u_char *sigb = NULL, *cp; + int is_webauthn = 0, ret = SSH_ERR_INTERNAL_ERROR, len = 0; struct sshbuf *b = NULL, *sigbuf = NULL, *original_signed = NULL; struct sshbuf *webauthn_wrapper = NULL, *webauthn_exts = NULL; char *ktype = NULL, *webauthn_origin = NULL; @@ -252,7 +254,7 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, if (detailsp != NULL) *detailsp = NULL; - if (key == NULL || key->ecdsa == NULL || + if (key == NULL || key->pkey == NULL || sshkey_type_plain(key->type) != KEY_ECDSA_SK || sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; @@ -308,7 +310,7 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, } #ifdef DEBUG_SK - fprintf(stderr, "%s: data: (len %zu)\n", __func__, datalen); + fprintf(stderr, "%s: data: (len %zu)\n", __func__, dlen); /* sshbuf_dump_data(data, datalen, stderr); */ fprintf(stderr, "%s: sig_r: %s\n", __func__, (tmp = BN_bn2hex(sig_r))); free(tmp); @@ -363,21 +365,43 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, (ret = sshbuf_putb(original_signed, webauthn_exts)) != 0 || (ret = sshbuf_put(original_signed, msghash, sizeof(msghash))) != 0) goto out; - /* Signature is over H(original_signed) */ - if ((ret = ssh_digest_buffer(SSH_DIGEST_SHA256, original_signed, - sighash, sizeof(sighash))) != 0) - goto out; details->sk_counter = sig_counter; details->sk_flags = sig_flags; #ifdef DEBUG_SK fprintf(stderr, "%s: signed buf:\n", __func__); sshbuf_dump(original_signed, stderr); - fprintf(stderr, "%s: signed hash:\n", __func__); - sshbuf_dump_data(sighash, sizeof(sighash), stderr); #endif + if ((md_ctx = EVP_MD_CTX_new()) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } + if ((len = i2d_ECDSA_SIG(esig, NULL)) <= 0) { + len = 0; + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + if ((sigb = calloc(1, len)) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } + cp = sigb; /* ASN1_item_i2d increments the pointer past the object */ + if (i2d_ECDSA_SIG(esig, &cp) != len) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } +#ifdef DEBUG_SK + fprintf(stderr, "%s: signed hash:\n", __func__); + sshbuf_dump_data(sigb, len, stderr); +#endif /* Verify it */ - switch (ECDSA_do_verify(sighash, sizeof(sighash), esig, key->ecdsa)) { + if (EVP_DigestVerifyInit(md_ctx, NULL, EVP_sha256(), NULL, + key->pkey) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + switch (EVP_DigestVerify(md_ctx, sigb, len, + sshbuf_ptr(original_signed), sshbuf_len(original_signed))) { case 1: ret = 0; break; @@ -397,7 +421,6 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, explicit_bzero(&sig_flags, sizeof(sig_flags)); explicit_bzero(&sig_counter, sizeof(sig_counter)); explicit_bzero(msghash, sizeof(msghash)); - explicit_bzero(sighash, sizeof(msghash)); explicit_bzero(apphash, sizeof(apphash)); sshkey_sig_details_free(details); sshbuf_free(webauthn_wrapper); @@ -410,6 +433,8 @@ ssh_ecdsa_sk_verify(const struct sshkey *key, BN_clear_free(sig_r); BN_clear_free(sig_s); free(ktype); + freezero(sigb, len); + EVP_MD_CTX_free(md_ctx); return ret; } diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c index 341c32409bc..695ed451e63 100644 --- a/ssh-ecdsa.c +++ b/ssh-ecdsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ecdsa.c,v 1.26 2023/03/08 04:43:12 guenther Exp $ */ +/* $OpenBSD: ssh-ecdsa.c,v 1.27 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -45,6 +45,61 @@ #include "openbsd-compat/openssl-compat.h" +int +sshkey_ecdsa_fixup_group(EVP_PKEY *k) +{ + int nids[] = { + NID_X9_62_prime256v1, + NID_secp384r1, +#ifdef OPENSSL_HAS_NISTP521 + NID_secp521r1, +#endif + -1 + }; + int nid = -1; + u_int i; + const EC_GROUP *g; + EC_KEY *ec = NULL; + EC_GROUP *eg = NULL; + + if ((ec = EVP_PKEY_get1_EC_KEY(k)) == NULL || + (g = EC_KEY_get0_group(ec)) == NULL) + goto out; + /* + * The group may be stored in a ASN.1 encoded private key in one of two + * ways: as a "named group", which is reconstituted by ASN.1 object ID + * or explicit group parameters encoded into the key blob. Only the + * "named group" case sets the group NID for us, but we can figure + * it out for the other case by comparing against all the groups that + * are supported. + */ + if ((nid = EC_GROUP_get_curve_name(g)) > 0) + goto out; + nid = -1; + for (i = 0; nids[i] != -1; i++) { + if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) + goto out; + if (EC_GROUP_cmp(g, eg, NULL) == 0) + break; + EC_GROUP_free(eg); + eg = NULL; + } + if (nids[i] == -1) + goto out; + + /* Use the group with the NID attached */ + EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); + if (EC_KEY_set_group(ec, eg) != 1 || + EVP_PKEY_set1_EC_KEY(k, ec) != 1) + goto out; + /* success */ + nid = nids[i]; + out: + EC_KEY_free(ec); + EC_GROUP_free(eg); + return nid; +} + static u_int ssh_ecdsa_size(const struct sshkey *key) { @@ -65,30 +120,16 @@ ssh_ecdsa_size(const struct sshkey *key) static void ssh_ecdsa_cleanup(struct sshkey *k) { - EC_KEY_free(k->ecdsa); - k->ecdsa = NULL; + EVP_PKEY_free(k->pkey); + k->pkey = NULL; } static int ssh_ecdsa_equal(const struct sshkey *a, const struct sshkey *b) { - const EC_GROUP *grp_a, *grp_b; - const EC_POINT *pub_a, *pub_b; - - if (a->ecdsa == NULL || b->ecdsa == NULL) + if (a->pkey == NULL || b->pkey == NULL) return 0; - if ((grp_a = EC_KEY_get0_group(a->ecdsa)) == NULL || - (grp_b = EC_KEY_get0_group(b->ecdsa)) == NULL) - return 0; - if ((pub_a = EC_KEY_get0_public_key(a->ecdsa)) == NULL || - (pub_b = EC_KEY_get0_public_key(b->ecdsa)) == NULL) - return 0; - if (EC_GROUP_cmp(grp_a, grp_b, NULL) != 0) - return 0; - if (EC_POINT_cmp(grp_a, pub_a, pub_b, NULL) != 0) - return 0; - - return 1; + return EVP_PKEY_cmp(a->pkey, b->pkey) == 1; } static int @@ -97,11 +138,11 @@ ssh_ecdsa_serialize_public(const struct sshkey *key, struct sshbuf *b, { int r; - if (key->ecdsa == NULL) + if (key->pkey == NULL) return SSH_ERR_INVALID_ARGUMENT; if ((r = sshbuf_put_cstring(b, sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || - (r = sshbuf_put_eckey(b, key->ecdsa)) != 0) + (r = sshbuf_put_ec_pkey(b, key->pkey)) != 0) return r; return 0; @@ -118,7 +159,7 @@ ssh_ecdsa_serialize_private(const struct sshkey *key, struct sshbuf *b, return r; } if ((r = sshbuf_put_bignum2(b, - EC_KEY_get0_private_key(key->ecdsa))) != 0) + EC_KEY_get0_private_key(EVP_PKEY_get0_EC_KEY(key->pkey)))) != 0) return r; return 0; } @@ -126,31 +167,64 @@ ssh_ecdsa_serialize_private(const struct sshkey *key, struct sshbuf *b, static int ssh_ecdsa_generate(struct sshkey *k, int bits) { - EC_KEY *private; + EVP_PKEY *res = NULL; + EVP_PKEY_CTX *ctx = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1) return SSH_ERR_KEY_LENGTH; - if ((private = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL) + + if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL) return SSH_ERR_ALLOC_FAIL; - if (EC_KEY_generate_key(private) != 1) { - EC_KEY_free(private); - return SSH_ERR_LIBCRYPTO_ERROR; + + if (EVP_PKEY_keygen_init(ctx) <= 0 || + EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, k->ecdsa_nid) <= 0 || + EVP_PKEY_keygen(ctx, &res) <= 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; } - EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE); - k->ecdsa = private; - return 0; + /* success */ + k->pkey = res; + res = NULL; + ret = 0; + out: + EVP_PKEY_free(res); + EVP_PKEY_CTX_free(ctx); + return ret; } static int ssh_ecdsa_copy_public(const struct sshkey *from, struct sshkey *to) { + const EC_KEY *ec_from; + EC_KEY *ec_to = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; + + ec_from = EVP_PKEY_get0_EC_KEY(from->pkey); + if (ec_from == NULL) + return SSH_ERR_LIBCRYPTO_ERROR; + to->ecdsa_nid = from->ecdsa_nid; - if ((to->ecdsa = EC_KEY_new_by_curve_name(from->ecdsa_nid)) == NULL) + if ((ec_to = EC_KEY_new_by_curve_name(from->ecdsa_nid)) == NULL) return SSH_ERR_ALLOC_FAIL; - if (EC_KEY_set_public_key(to->ecdsa, - EC_KEY_get0_public_key(from->ecdsa)) != 1) - return SSH_ERR_LIBCRYPTO_ERROR; /* caller will free k->ecdsa */ - return 0; + if (EC_KEY_set_public_key(ec_to, + EC_KEY_get0_public_key(ec_from)) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + EVP_PKEY_free(to->pkey); + if ((to->pkey = EVP_PKEY_new()) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (EVP_PKEY_set1_EC_KEY(to->pkey, ec_to) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + ret = 0; + out: + EC_KEY_free(ec_to); + return ret; } static int @@ -159,6 +233,8 @@ ssh_ecdsa_deserialize_public(const char *ktype, struct sshbuf *b, { int r; char *curve = NULL; + EVP_PKEY *pkey = NULL; + EC_KEY *ec = NULL; if ((key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype)) == -1) return SSH_ERR_INVALID_ARGUMENT; @@ -168,31 +244,39 @@ ssh_ecdsa_deserialize_public(const char *ktype, struct sshbuf *b, r = SSH_ERR_EC_CURVE_MISMATCH; goto out; } - EC_KEY_free(key->ecdsa); - key->ecdsa = NULL; - if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL) { + if ((ec = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - if ((r = sshbuf_get_eckey(b, key->ecdsa)) != 0) + if ((r = sshbuf_get_eckey(b, ec)) != 0) goto out; - if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), - EC_KEY_get0_public_key(key->ecdsa)) != 0) { + if (sshkey_ec_validate_public(EC_KEY_get0_group(ec), + EC_KEY_get0_public_key(ec)) != 0) { r = SSH_ERR_KEY_INVALID_EC_VALUE; goto out; } + if ((pkey = EVP_PKEY_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (EVP_PKEY_set1_EC_KEY(pkey, ec) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + EVP_PKEY_free(key->pkey); + key->pkey = pkey; + pkey = NULL; /* success */ r = 0; #ifdef DEBUG_PK - sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), - EC_KEY_get0_public_key(key->ecdsa)); + sshkey_dump_ec_point( + EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(key->pkey)), + EC_KEY_get0_public_key(EVP_PKEY_get0_EC_KEY(key->pkey))); #endif out: + EC_KEY_free(ec); + EVP_PKEY_free(pkey); free(curve); - if (r != 0) { - EC_KEY_free(key->ecdsa); - key->ecdsa = NULL; - } return r; } @@ -202,6 +286,7 @@ ssh_ecdsa_deserialize_private(const char *ktype, struct sshbuf *b, { int r; BIGNUM *exponent = NULL; + EC_KEY *ec = NULL; if (!sshkey_is_cert(key)) { if ((r = ssh_ecdsa_deserialize_public(ktype, b, key)) != 0) @@ -209,16 +294,25 @@ ssh_ecdsa_deserialize_private(const char *ktype, struct sshbuf *b, } if ((r = sshbuf_get_bignum2(b, &exponent)) != 0) goto out; - if (EC_KEY_set_private_key(key->ecdsa, exponent) != 1) { + if ((ec = EVP_PKEY_get1_EC_KEY(key->pkey)) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + if (EC_KEY_set_private_key(ec, exponent) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - if ((r = sshkey_ec_validate_private(key->ecdsa)) != 0) + if ((r = sshkey_ec_validate_private(ec)) != 0) goto out; + if (EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } /* success */ r = 0; out: BN_clear_free(exponent); + EC_KEY_free(ec); return r; } @@ -229,34 +323,35 @@ ssh_ecdsa_sign(struct sshkey *key, const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { ECDSA_SIG *esig = NULL; + unsigned char *sigb = NULL; + const unsigned char *psig; const BIGNUM *sig_r, *sig_s; int hash_alg; - u_char digest[SSH_DIGEST_MAX_LENGTH]; - size_t len, hlen; + size_t slen = 0; struct sshbuf *b = NULL, *bb = NULL; - int ret = SSH_ERR_INTERNAL_ERROR; + int len = 0, ret = SSH_ERR_INTERNAL_ERROR; if (lenp != NULL) *lenp = 0; if (sigp != NULL) *sigp = NULL; - if (key == NULL || key->ecdsa == NULL || + if (key == NULL || key->pkey == NULL || sshkey_type_plain(key->type) != KEY_ECDSA) return SSH_ERR_INVALID_ARGUMENT; - if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || - (hlen = ssh_digest_bytes(hash_alg)) == 0) + if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) return SSH_ERR_INTERNAL_ERROR; - if ((ret = ssh_digest_memory(hash_alg, data, dlen, - digest, sizeof(digest))) != 0) + + if ((ret = sshkey_pkey_digest_sign(key->pkey, hash_alg, &sigb, &slen, + data, dlen)) != 0) goto out; - if ((esig = ECDSA_do_sign(digest, hlen, key->ecdsa)) == NULL) { + psig = sigb; + if ((esig = d2i_ECDSA_SIG(NULL, &psig, slen)) == NULL) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - if ((bb = sshbuf_new()) == NULL || (b = sshbuf_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; @@ -280,7 +375,7 @@ ssh_ecdsa_sign(struct sshkey *key, *lenp = len; ret = 0; out: - explicit_bzero(digest, sizeof(digest)); + freezero(sigb, slen); sshbuf_free(b); sshbuf_free(bb); ECDSA_SIG_free(esig); @@ -295,20 +390,18 @@ ssh_ecdsa_verify(const struct sshkey *key, { ECDSA_SIG *esig = NULL; BIGNUM *sig_r = NULL, *sig_s = NULL; - int hash_alg; - u_char digest[SSH_DIGEST_MAX_LENGTH]; - size_t hlen; + int hash_alg, len = 0; int ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL, *sigbuf = NULL; char *ktype = NULL; + unsigned char *sigb = NULL, *cp; - if (key == NULL || key->ecdsa == NULL || + if (key == NULL || key->pkey == NULL || sshkey_type_plain(key->type) != KEY_ECDSA || sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; - if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1 || - (hlen = ssh_digest_bytes(hash_alg)) == 0) + if ((hash_alg = sshkey_ec_nid_to_hash_alg(key->ecdsa_nid)) == -1) return SSH_ERR_INTERNAL_ERROR; /* fetch signature */ @@ -334,6 +427,11 @@ ssh_ecdsa_verify(const struct sshkey *key, ret = SSH_ERR_INVALID_FORMAT; goto out; } + if (sshbuf_len(sigbuf) != 0) { + ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; + goto out; + } + if ((esig = ECDSA_SIG_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; @@ -344,28 +442,26 @@ ssh_ecdsa_verify(const struct sshkey *key, } sig_r = sig_s = NULL; /* transferred */ - if (sshbuf_len(sigbuf) != 0) { - ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; + if ((len = i2d_ECDSA_SIG(esig, NULL)) <= 0) { + len = 0; + ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - if ((ret = ssh_digest_memory(hash_alg, data, dlen, - digest, sizeof(digest))) != 0) - goto out; - - switch (ECDSA_do_verify(digest, hlen, esig, key->ecdsa)) { - case 1: - ret = 0; - break; - case 0: - ret = SSH_ERR_SIGNATURE_INVALID; + if ((sigb = calloc(1, len)) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; goto out; - default: + } + cp = sigb; /* ASN1_item_i2d increments the pointer past the object */ + if (i2d_ECDSA_SIG(esig, &cp) != len) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - + if ((ret = sshkey_pkey_digest_verify(key->pkey, hash_alg, + data, dlen, sigb, len)) != 0) + goto out; + /* success */ out: - explicit_bzero(digest, sizeof(digest)); + freezero(sigb, len); sshbuf_free(sigbuf); sshbuf_free(b); ECDSA_SIG_free(esig); diff --git a/ssh-keygen.0 b/ssh-keygen.0 index a731a7fa856..799f32365f9 100644 --- a/ssh-keygen.0 +++ b/ssh-keygen.0 @@ -319,12 +319,14 @@ DESCRIPTION -t ecdsa | ecdsa-sk | ed25519 | ed25519-sk | rsa Specifies the type of key to create. The possible values are - M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ecdsa-skM-bM-^@M-^], M-bM-^@M-^\ed25519M-bM-^@M-^], M-bM-^@M-^\ed25519-skM-bM-^@M-^], or M-bM-^@M-^\rsaM-bM-^@M-^]. + M-bM-^@M-^\ecdsaM-bM-^@M-^], M-bM-^@M-^\ecdsa-skM-bM-^@M-^], M-bM-^@M-^\ed25519 (the default),M-bM-^@M-^] M-bM-^@M-^\ed25519-skM-bM-^@M-^], or + M-bM-^@M-^\rsaM-bM-^@M-^]. This flag may also be used to specify the desired signature type when signing certificates using an RSA CA key. The available RSA signature variants are M-bM-^@M-^\ssh-rsaM-bM-^@M-^] (SHA1 signatures, not - recommended), M-bM-^@M-^\rsa-sha2-256M-bM-^@M-^], and M-bM-^@M-^\rsa-sha2-512M-bM-^@M-^] (the default). + recommended), M-bM-^@M-^\rsa-sha2-256M-bM-^@M-^], and M-bM-^@M-^\rsa-sha2-512M-bM-^@M-^] (the default for + RSA keys). -U When used in combination with -s or -Y sign, this option indicates that a CA key resides in a ssh-agent(1). See the @@ -654,10 +656,9 @@ CERTIFICATES verify-required Require signatures made using this key indicate that the user was - first verified. This option only makes sense for the FIDO - authenticator algorithms ecdsa-sk and ed25519-sk. Currently PIN - authentication is the only supported verification method, but - other methods may be supported in the future. + first verified, e.g. by PIN or on-token biometrics. This option + only makes sense for the FIDO authenticator algorithms ecdsa-sk + and ed25519-sk. At present, no standard options are valid for host keys. @@ -904,4 +905,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.5 June 17, 2024 OpenBSD 7.5 +OpenBSD 7.6 November 27, 2024 OpenBSD 7.6 diff --git a/ssh-keygen.1 b/ssh-keygen.1 index df6803fd935..00246a861ac 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.232 2024/06/17 13:50:18 naddy Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.234 2024/11/27 13:00:23 djm Exp $ .\" .\" Author: Tatu Ylonen .\" Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -35,7 +35,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: June 17 2024 $ +.Dd $Mdocdate: November 27 2024 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -581,7 +581,7 @@ Specifies the type of key to create. The possible values are .Dq ecdsa , .Dq ecdsa-sk , -.Dq ed25519 , +.Dq ed25519 (the default), .Dq ed25519-sk , or .Dq rsa . @@ -594,7 +594,7 @@ The available RSA signature variants are .Dq rsa-sha2-256 , and .Dq rsa-sha2-512 -(the default). +(the default for RSA keys). .It Fl U When used in combination with .Fl s @@ -1041,13 +1041,11 @@ format. .Pp .It Ic verify-required Require signatures made using this key indicate that the user was first -verified. +verified, e.g. by PIN or on-token biometrics. This option only makes sense for the FIDO authenticator algorithms .Cm ecdsa-sk and .Cm ed25519-sk . -Currently PIN authentication is the only supported verification method, -but other methods may be supported in the future. .El .Pp At present, no standard options are valid for host keys. diff --git a/ssh-keygen.c b/ssh-keygen.c index 41896aca67b..7033815b2da 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.472 2024/01/11 01:45:36 djm Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.477 2024/12/04 14:24:20 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -273,7 +273,7 @@ ask_filename(struct passwd *pw, const char *prompt) name = _PATH_SSH_CLIENT_ID_ED25519; #endif /* WINDOWS */ else { - switch (sshkey_type_from_name(key_type_name)) { + switch (sshkey_type_from_shortname(key_type_name)) { #ifdef WITH_DSA case KEY_DSA_CERT: case KEY_DSA: @@ -325,7 +325,7 @@ ask_filename(struct passwd *pw, const char *prompt) static struct sshkey * load_identity(const char *filename, char **commentp) { - char *pass; + char *prompt, *pass; struct sshkey *prv; int r; @@ -337,8 +337,11 @@ load_identity(const char *filename, char **commentp) fatal_r(r, "Load key \"%s\"", filename); if (identity_passphrase) pass = xstrdup(identity_passphrase); - else - pass = read_passphrase("Enter passphrase: ", RP_ALLOW_STDIN); + else { + xasprintf(&prompt, "Enter passphrase for \"%s\": ", filename); + pass = read_passphrase(prompt, RP_ALLOW_STDIN); + free(prompt); + } r = sshkey_load_private(filename, pass, &prv, commentp); freezero(pass, strlen(pass)); if (r != 0) @@ -387,7 +390,8 @@ do_convert_to_pkcs8(struct sshkey *k) { switch (sshkey_type_plain(k->type)) { case KEY_RSA: - if (!PEM_write_RSA_PUBKEY(stdout, k->rsa)) + if (!PEM_write_RSA_PUBKEY(stdout, + EVP_PKEY_get0_RSA(k->pkey))) fatal("PEM_write_RSA_PUBKEY failed"); break; #ifdef WITH_DSA @@ -398,7 +402,8 @@ do_convert_to_pkcs8(struct sshkey *k) #endif #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: - if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa)) + if (!PEM_write_EC_PUBKEY(stdout, + EVP_PKEY_get0_EC_KEY(k->pkey))) fatal("PEM_write_EC_PUBKEY failed"); break; #endif @@ -413,7 +418,8 @@ do_convert_to_pem(struct sshkey *k) { switch (sshkey_type_plain(k->type)) { case KEY_RSA: - if (!PEM_write_RSAPublicKey(stdout, k->rsa)) + if (!PEM_write_RSAPublicKey(stdout, + EVP_PKEY_get0_RSA(k->pkey))) fatal("PEM_write_RSAPublicKey failed"); break; #ifdef WITH_DSA @@ -424,7 +430,8 @@ do_convert_to_pem(struct sshkey *k) #endif #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: - if (!PEM_write_EC_PUBKEY(stdout, k->ecdsa)) + if (!PEM_write_EC_PUBKEY(stdout, + EVP_PKEY_get0_EC_KEY(k->pkey))) fatal("PEM_write_EC_PUBKEY failed"); break; #endif @@ -502,6 +509,8 @@ do_convert_private_ssh2(struct sshbuf *b) #endif BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; BIGNUM *rsa_p = NULL, *rsa_q = NULL, *rsa_iqmp = NULL; + BIGNUM *rsa_dmp1 = NULL, *rsa_dmq1 = NULL; + RSA *rsa = NULL; if ((r = sshbuf_get_u32(b, &magic)) != 0) fatal_fr(r, "parse magic"); @@ -596,15 +605,25 @@ do_convert_private_ssh2(struct sshbuf *b) buffer_get_bignum_bits(b, rsa_iqmp); buffer_get_bignum_bits(b, rsa_q); buffer_get_bignum_bits(b, rsa_p); - if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, rsa_d)) + if ((r = ssh_rsa_complete_crt_parameters(rsa_d, rsa_p, rsa_q, + rsa_iqmp, &rsa_dmp1, &rsa_dmq1)) != 0) + fatal_fr(r, "generate RSA CRT parameters"); + if ((key->pkey = EVP_PKEY_new()) == NULL) + fatal_f("EVP_PKEY_new failed"); + if ((rsa = RSA_new()) == NULL) + fatal_f("RSA_new failed"); + if (!RSA_set0_key(rsa, rsa_n, rsa_e, rsa_d)) fatal_f("RSA_set0_key failed"); rsa_n = rsa_e = rsa_d = NULL; /* transferred */ - if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q)) + if (!RSA_set0_factors(rsa, rsa_p, rsa_q)) fatal_f("RSA_set0_factors failed"); rsa_p = rsa_q = NULL; /* transferred */ - if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0) - fatal_fr(r, "generate RSA parameters"); - BN_clear_free(rsa_iqmp); + if (RSA_set0_crt_params(rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp) != 1) + fatal_f("RSA_set0_crt_params failed"); + rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; + if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) + fatal_f("EVP_PKEY_set1_RSA failed"); + RSA_free(rsa); alg = "rsa-sha2-256"; break; } @@ -724,7 +743,8 @@ do_convert_from_pkcs8(struct sshkey **k, int *private) if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); (*k)->type = KEY_RSA; - (*k)->rsa = EVP_PKEY_get1_RSA(pubkey); + (*k)->pkey = pubkey; + pubkey = NULL; break; #ifdef WITH_DSA case EVP_PKEY_DSA: @@ -738,9 +758,11 @@ do_convert_from_pkcs8(struct sshkey **k, int *private) case EVP_PKEY_EC: if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); + if (((*k)->ecdsa_nid = sshkey_ecdsa_fixup_group(pubkey)) == -1) + fatal("sshkey_ecdsa_fixup_group failed"); (*k)->type = KEY_ECDSA; - (*k)->ecdsa = EVP_PKEY_get1_EC_KEY(pubkey); - (*k)->ecdsa_nid = sshkey_ecdsa_key_to_nid((*k)->ecdsa); + (*k)->pkey = pubkey; + pubkey = NULL; break; #endif default: @@ -762,8 +784,12 @@ do_convert_from_pem(struct sshkey **k, int *private) if ((rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL)) != NULL) { if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) fatal("sshkey_new failed"); + if (((*k)->pkey = EVP_PKEY_new()) == NULL) + fatal("EVP_PKEY_new failed"); (*k)->type = KEY_RSA; - (*k)->rsa = rsa; + if (EVP_PKEY_set1_RSA((*k)->pkey, rsa) != 1) + fatal("EVP_PKEY_set1_RSA failed"); + RSA_free(rsa); fclose(fp); return; } @@ -811,13 +837,15 @@ do_convert_from(struct passwd *pw) #endif #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: - ok = PEM_write_ECPrivateKey(stdout, k->ecdsa, NULL, - NULL, 0, NULL, NULL); + ok = PEM_write_ECPrivateKey(stdout, + EVP_PKEY_get0_EC_KEY(k->pkey), NULL, NULL, 0, + NULL, NULL); break; #endif case KEY_RSA: - ok = PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, - NULL, 0, NULL, NULL); + ok = PEM_write_RSAPrivateKey(stdout, + EVP_PKEY_get0_RSA(k->pkey), NULL, NULL, 0, + NULL, NULL); break; default: fatal_f("unsupported key type %s", sshkey_type(k)); @@ -992,7 +1020,7 @@ do_fingerprint(struct passwd *pw) while (getline(&line, &linesize, f) != -1) { lnum++; cp = line; - cp[strcspn(cp, "\n")] = '\0'; + cp[strcspn(cp, "\r\n")] = '\0'; /* Trim leading space and comments */ cp = line + strspn(line, " \t"); if (*cp == '#' || *cp == '\0') @@ -1127,7 +1155,7 @@ do_gen_all_hostkeys(struct passwd *pw) } printf("%s ", key_types[i].key_type_display); fflush(stdout); - type = sshkey_type_from_name(key_types[i].key_type); + type = sshkey_type_from_shortname(key_types[i].key_type); if ((fd = mkstemp(prv_tmp)) == -1) { error("Could not save your private key in %s: %s", prv_tmp, strerror(errno)); @@ -1839,7 +1867,7 @@ do_ca_sign(struct passwd *pw, const char *ca_key_path, int prefer_agent, free(tmp); if (key_type_name != NULL) { - if (sshkey_type_from_name(key_type_name) != ca->type) { + if (sshkey_type_from_shortname(key_type_name) != ca->type) { fatal("CA key type %s doesn't match specified %s", sshkey_ssh_name(ca), key_type_name); } @@ -3038,7 +3066,9 @@ do_moduli_gen(const char *out_file, char **opts, size_t nopts) } } - if ((out = fopen(out_file, "w")) == NULL) { + if (strcmp(out_file, "-") == 0) + out = stdout; + else if ((out = fopen(out_file, "w")) == NULL) { fatal("Couldn't open modulus candidate file \"%s\": %s", out_file, strerror(errno)); } @@ -3103,7 +3133,9 @@ do_moduli_screen(const char *out_file, char **opts, size_t nopts) } } - if ((out = fopen(out_file, "a")) == NULL) { + if (strcmp(out_file, "-") == 0) + out = stdout; + else if ((out = fopen(out_file, "a")) == NULL) { fatal("Couldn't open moduli file \"%s\": %s", out_file, strerror(errno)); } @@ -3146,17 +3178,22 @@ read_check_passphrase(const char *prompt1, const char *prompt2, } static char * -private_key_passphrase(void) +private_key_passphrase(const char *path) { + char *prompt, *ret; + if (identity_passphrase) return xstrdup(identity_passphrase); if (identity_new_passphrase) return xstrdup(identity_new_passphrase); - return read_check_passphrase( - "Enter passphrase (empty for no passphrase): ", + xasprintf(&prompt, "Enter passphrase for \"%s\" " + "(empty for no passphrase): ", path); + ret = read_check_passphrase(prompt, "Enter same passphrase again: ", "Passphrases do not match. Try again."); + free(prompt); + return ret; } static char * @@ -3256,7 +3293,7 @@ do_download_sk(const char *skprovider, const char *device) /* Save the key with the application string as the comment */ if (pass == NULL) - pass = private_key_passphrase(); + pass = private_key_passphrase(path); if ((r = sshkey_save_private(key, path, pass, // CodeQL [SM02311] false positive: private_key_passphrase() will never return null. key->sk_application, private_key_format, openssh_format_cipher, rounds)) != 0) { @@ -3857,7 +3894,7 @@ main(int argc, char **argv) if (key_type_name == NULL) key_type_name = DEFAULT_KEY_TYPE_NAME; - type = sshkey_type_from_name(key_type_name); + type = sshkey_type_from_shortname(key_type_name); type_bits_valid(type, key_type_name, &bits); if (!quiet) @@ -3970,7 +4007,7 @@ main(int argc, char **argv) exit(1); /* Determine the passphrase for the private key */ - passphrase = private_key_passphrase(); + passphrase = private_key_passphrase(identity_file); if (identity_comment) { strlcpy(comment, identity_comment, sizeof(comment)); } else { diff --git a/ssh-keyscan.0 b/ssh-keyscan.0 index 11039909446..382d1608acb 100644 --- a/ssh-keyscan.0 +++ b/ssh-keyscan.0 @@ -120,4 +120,4 @@ AUTHORS Davison added support for protocol version 2. -OpenBSD 7.5 June 17, 2024 OpenBSD 7.5 +OpenBSD 7.6 June 17, 2024 OpenBSD 7.6 diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 548eaab83ee..3436c0b5c7c 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.158 2024/06/14 00:25:25 djm Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.165 2024/12/06 15:17:15 djm Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -303,6 +303,7 @@ keygrab_ssh2(con *c) #endif c->c_ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; c->c_ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client; + c->c_ssh->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_client; ssh_set_verify_host_key_callback(c->c_ssh, key_print_wrapper); /* * do the key-exchange until an error occurs or until @@ -587,7 +588,7 @@ conloop(void) for (i = 0; i < maxfd; i++) { if (read_wait[i].revents & (POLLHUP|POLLERR|POLLNVAL)) confree(i); - else if (read_wait[i].revents & (POLLIN|POLLHUP)) + else if (read_wait[i].revents & (POLLIN)) conread(i); } @@ -649,22 +650,10 @@ do_host(char *host) if (addr_cmp(&addr, &end_addr) == 0) break; addr_increment(&addr); - }; + } } } -void -sshfatal(const char *file, const char *func, int line, int showfunc, - LogLevel level, const char *suffix, const char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - sshlogv(file, func, line, showfunc, level, suffix, fmt, args); - va_end(args); - cleanup_exit(255); -} - static void usage(void) { @@ -751,7 +740,7 @@ main(int argc, char **argv) get_keytypes = 0; tname = strtok(optarg, ","); while (tname) { - int type = sshkey_type_from_name(tname); + int type = sshkey_type_from_shortname(tname); switch (type) { #ifdef WITH_DSA @@ -813,6 +802,7 @@ main(int argc, char **argv) for (j = 0; j < maxfd; j++) read_wait[j].fd = -1; + ssh_signal(SIGPIPE, SIG_IGN); for (j = 0; j < fopt_count; j++) { if (argv[j] == NULL) fp = stdin; diff --git a/ssh-keysign.0 b/ssh-keysign.0 index 577955d1b54..f1e0e096413 100644 --- a/ssh-keysign.0 +++ b/ssh-keysign.0 @@ -47,4 +47,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 7.5 June 17, 2024 OpenBSD 7.5 +OpenBSD 7.6 June 17, 2024 OpenBSD 7.6 diff --git a/ssh-keysign.c b/ssh-keysign.c index 968344e7946..955f7b0abad 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keysign.c,v 1.74 2024/04/30 05:53:03 djm Exp $ */ +/* $OpenBSD: ssh-keysign.c,v 1.75 2025/02/15 01:48:30 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -222,7 +222,7 @@ main(int argc, char **argv) /* verify that ssh-keysign is enabled by the admin */ initialize_options(&options); - (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", + (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", "", &options, 0, NULL); (void)fill_default_options(&options); if (options.enable_ssh_keysign != 1) diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c index 843a10e6802..69e014ba176 100644 --- a/ssh-pkcs11-client.c +++ b/ssh-pkcs11-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-client.c,v 1.19 2023/12/18 14:46:56 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-client.c,v 1.20 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved. @@ -166,7 +166,7 @@ find_helper(void) char *ep; DWORD n; size_t len = 0; - + _dupenv_s(&helper, &len, "SSH_PKCS11_HELPER"); if (helper == NULL || len == 0) { if ((helper = find_helper_in_module_path()) == NULL) @@ -424,14 +424,17 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding) #endif /* WINDOWS */ if (padding != RSA_PKCS1_PADDING) goto fail; - key = sshkey_new(KEY_UNSPEC); - if (key == NULL) { + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) { error_f("sshkey_new failed"); goto fail; } + if ((key->pkey = EVP_PKEY_new()) == NULL || + EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) { + error_f("pkey setup failed"); + goto fail; + } + key->type = KEY_RSA; - RSA_up_ref(rsa); - key->rsa = rsa; if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { error_fr(r, "encode key"); goto fail; @@ -511,21 +514,21 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, fatal_f("no helper for PKCS11 key"); debug3_f("signing with PKCS11 provider %s", helper->path); #endif /* WINDOWS */ - nid = sshkey_ecdsa_key_to_nid(ec); - if (nid < 0) { - error_f("couldn't get curve nid"); + if ((key = sshkey_new(KEY_UNSPEC)) == NULL) { + error_f("sshkey_new failed"); goto fail; } - - key = sshkey_new(KEY_UNSPEC); - if (key == NULL) { - error_f("sshkey_new failed"); + if ((key->pkey = EVP_PKEY_new()) == NULL || + EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) { + error("pkey setup failed"); + goto fail; + } + if ((nid = sshkey_ecdsa_pkey_to_nid(key->pkey)) < 0) { + error("couldn't get curve nid"); goto fail; } - key->ecdsa = ec; key->ecdsa_nid = nid; key->type = KEY_ECDSA; - EC_KEY_up_ref(ec); if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) { error_fr(r, "encode key"); @@ -546,7 +549,7 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv, sshbuf_reset(msg); #ifdef WINDOWS - if (recv_msg(fd, msg) == SSH2_AGENT_SIGN_RESPONSE) { + if (recv_msg(fd, msg) == SSH2_AGENT_SIGN_RESPONSE) { #else if (recv_msg(helper->fd, msg) == SSH2_AGENT_SIGN_RESPONSE) { #endif /* WINDOWS */ @@ -593,10 +596,10 @@ static void wrap_key(struct sshkey *k) { if (k->type == KEY_RSA) - RSA_set_method(k->rsa, helper_rsa); + RSA_set_method(k->pkey, helper_rsa); #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) else if (k->type == KEY_ECDSA) - EC_KEY_set_method(k->ecdsa, helper_ecdsa); + EC_KEY_set_method(k->pkey, helper_ecdsa); #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ else fatal_f("unknown key type"); @@ -607,16 +610,31 @@ wrap_key(struct sshkey *k) static void wrap_key(struct helper *helper, struct sshkey *k) { + RSA *rsa = NULL; + EC_KEY *ecdsa = NULL; + debug3_f("wrap %s for provider %s", sshkey_type(k), helper->path); if (k->type == KEY_RSA) { - RSA_set_method(k->rsa, helper->rsa_meth); + if ((rsa = EVP_PKEY_get1_RSA(k->pkey)) == NULL) + fatal_f("no RSA key"); + if (RSA_set_method(rsa, helper->rsa_meth) != 1) + fatal_f("RSA_set_method failed"); if (helper->nrsa++ >= INT_MAX) fatal_f("RSA refcount error"); + if (EVP_PKEY_set1_RSA(k->pkey, rsa) != 1) + fatal_f("EVP_PKEY_set1_RSA failed"); + RSA_free(rsa); #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) } else if (k->type == KEY_ECDSA) { - EC_KEY_set_method(k->ecdsa, helper->ec_meth); + if ((ecdsa = EVP_PKEY_get1_EC_KEY(k->pkey)) == NULL) + fatal_f("no ECDSA key"); + if (EC_KEY_set_method(ecdsa, helper->ec_meth) != 1) + fatal_f("EC_KEY_set_method failed"); if (helper->nec++ >= INT_MAX) fatal_f("EC refcount error"); + if (EVP_PKEY_set1_EC_KEY(k->pkey, ecdsa) != 1) + fatal_f("EVP_PKEY_set1_EC_KEY failed"); + EC_KEY_free(ecdsa); #endif } else fatal_f("unknown key type"); @@ -668,6 +686,10 @@ pkcs11_make_cert(const struct sshkey *priv, struct helper *helper = NULL; struct sshkey *ret; int r; + RSA *rsa_priv = NULL, *rsa_cert = NULL; +#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) + EC_KEY *ec_priv = NULL, *ec_cert = NULL; +#endif debug3_f("private key type %s cert type %s", sshkey_type(priv), sshkey_type(certpub)); @@ -680,24 +702,42 @@ pkcs11_make_cert(const struct sshkey *priv, } *certprivp = NULL; if (priv->type == KEY_RSA) { - if ((helper = helper_by_rsa(priv->rsa)) == NULL || + if ((rsa_priv = EVP_PKEY_get1_RSA(priv->pkey)) == NULL) + fatal_f("no RSA pkey"); + if ((helper = helper_by_rsa(rsa_priv)) == NULL || helper->fd == -1) fatal_f("no helper for PKCS11 RSA key"); if ((r = sshkey_from_private(priv, &ret)) != 0) fatal_fr(r, "copy key"); - RSA_set_method(ret->rsa, helper->rsa_meth); + if ((rsa_cert = EVP_PKEY_get1_RSA(ret->pkey)) == NULL) + fatal_f("no RSA cert pkey"); + if (RSA_set_method(rsa_cert, helper->rsa_meth) != 1) + fatal_f("RSA_set_method failed"); if (helper->nrsa++ >= INT_MAX) fatal_f("RSA refcount error"); + if (EVP_PKEY_set1_RSA(ret->pkey, rsa_cert) != 1) + fatal_f("EVP_PKEY_set1_RSA failed"); + RSA_free(rsa_priv); + RSA_free(rsa_cert); #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) } else if (priv->type == KEY_ECDSA) { - if ((helper = helper_by_ec(priv->ecdsa)) == NULL || + if ((ec_priv = EVP_PKEY_get1_EC_KEY(priv->pkey)) == NULL) + fatal_f("no EC pkey"); + if ((helper = helper_by_ec(ec_priv)) == NULL || helper->fd == -1) fatal_f("no helper for PKCS11 EC key"); if ((r = sshkey_from_private(priv, &ret)) != 0) fatal_fr(r, "copy key"); - EC_KEY_set_method(ret->ecdsa, helper->ec_meth); + if ((ec_cert = EVP_PKEY_get1_EC_KEY(ret->pkey)) == NULL) + fatal_f("no EC cert pkey"); + if (EC_KEY_set_method(ec_cert, helper->ec_meth) != 1) + fatal_f("EC_KEY_set_method failed"); if (helper->nec++ >= INT_MAX) fatal_f("EC refcount error"); + if (EVP_PKEY_set1_EC_KEY(ret->pkey, ec_cert) != 1) + fatal_f("EVP_PKEY_set1_EC_KEY failed"); + EC_KEY_free(ec_priv); + EC_KEY_free(ec_cert); #endif } else fatal_f("unknown key type %s", sshkey_type(priv)); @@ -716,7 +756,7 @@ pkcs11_make_cert(const struct sshkey *priv, static int pkcs11_start_helper_methods(struct helper *helper) { - RSA_METHOD *rsa_meth; + RSA_METHOD *rsa_meth = NULL; EC_KEY_METHOD *ec_meth = NULL; #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) int (*ec_init)(EC_KEY *key); @@ -919,7 +959,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp, return -1; #else struct pkcs11_provider *p; - if (fd < 0 && pkcs11_start_helper() < 0) + if (fd < 0 && pkcs11_start_helper() < 0) return (-1); #endif /* WINDOWS */ diff --git a/ssh-pkcs11-helper.0 b/ssh-pkcs11-helper.0 index 5645872592b..42a6a208e83 100644 --- a/ssh-pkcs11-helper.0 +++ b/ssh-pkcs11-helper.0 @@ -32,4 +32,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 7.5 April 29, 2022 OpenBSD 7.5 +OpenBSD 7.6 April 29, 2022 OpenBSD 7.6 diff --git a/ssh-pkcs11-helper.c b/ssh-pkcs11-helper.c index 5c3eaaeb019..a8154f21c05 100644 --- a/ssh-pkcs11-helper.c +++ b/ssh-pkcs11-helper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11-helper.c,v 1.26 2021/11/18 03:31:44 djm Exp $ */ +/* $OpenBSD: ssh-pkcs11-helper.c,v 1.27 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * @@ -45,6 +45,9 @@ #ifdef ENABLE_PKCS11 #ifdef WITH_OPENSSL +#include +#include +#include /* borrows code from sftp-server and ssh-agent */ @@ -185,10 +188,17 @@ static void process_sign(void) { u_char *blob, *data, *signature = NULL; - size_t blen, dlen, slen = 0; - int r, ok = -1; - struct sshkey *key, *found; + size_t blen, dlen; + u_int slen = 0; + int len, r, ok = -1; + struct sshkey *key = NULL, *found; struct sshbuf *msg; +#ifdef WITH_OPENSSL + RSA *rsa = NULL; +#ifdef OPENSSL_HAS_ECC + EC_KEY *ecdsa = NULL; +#endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL */ /* XXX support SHA2 signature flags */ if ((r = sshbuf_get_string(iqueue, &blob, &blen)) != 0 || @@ -198,41 +208,47 @@ process_sign(void) if ((r = sshkey_from_blob(blob, blen, &key)) != 0) fatal_fr(r, "decode key"); - else { - if ((found = lookup_key(key)) != NULL) { + if ((found = lookup_key(key)) == NULL) + goto reply; + + /* XXX use pkey API properly for signing */ + switch (key->type) { #ifdef WITH_OPENSSL - int ret; - - if (key->type == KEY_RSA) { - slen = RSA_size(key->rsa); - signature = xmalloc(slen); - ret = RSA_private_encrypt(dlen, data, signature, - found->rsa, RSA_PKCS1_PADDING); - if (ret != -1) { - slen = ret; - ok = 0; - } + case KEY_RSA: + if ((rsa = EVP_PKEY_get1_RSA(found->pkey)) == NULL) + fatal_f("no RSA in pkey"); + if ((len = RSA_size(rsa)) < 0) + fatal_f("bad RSA length"); + signature = xmalloc(len); + if ((len = RSA_private_encrypt(dlen, data, signature, + rsa, RSA_PKCS1_PADDING)) < 0) { + error_f("RSA_private_encrypt failed"); + goto reply; + } + slen = (u_int)len; + break; #ifdef OPENSSL_HAS_ECC - } else if (key->type == KEY_ECDSA) { - u_int xslen = ECDSA_size(key->ecdsa); - - signature = xmalloc(xslen); - /* "The parameter type is ignored." */ - ret = ECDSA_sign(-1, data, dlen, signature, - &xslen, found->ecdsa); - if (ret != 0) - ok = 0; - else - error_f("ECDSA_sign returned %d", ret); - slen = xslen; + case KEY_ECDSA: + if ((ecdsa = EVP_PKEY_get1_EC_KEY(found->pkey)) == NULL) + fatal_f("no ECDSA in pkey"); + if ((len = ECDSA_size(ecdsa)) < 0) + fatal_f("bad ECDSA length"); + slen = (u_int)len; + signature = xmalloc(slen); + /* "The parameter type is ignored." */ + if (!ECDSA_sign(-1, data, dlen, signature, &slen, ecdsa)) { + error_f("ECDSA_sign failed"); + goto reply; + } + break; #endif /* OPENSSL_HAS_ECC */ - } else - error_f("don't know how to sign with key " - "type %d", (int)key->type); #endif /* WITH_OPENSSL */ - } - sshkey_free(key); + default: + fatal_f("unsupported key type %d", key->type); } + /* success */ + ok = 0; + reply: if ((msg = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); if (ok == 0) { @@ -243,6 +259,11 @@ process_sign(void) if ((r = sshbuf_put_u8(msg, SSH2_AGENT_FAILURE)) != 0) fatal_fr(r, "compose failure response"); } + sshkey_free(key); + RSA_free(rsa); +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) + EC_KEY_free(ecdsa); +#endif free(data); free(blob); free(signature); diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c index 1e76e8b2bb3..31b9360f0ad 100644 --- a/ssh-pkcs11.c +++ b/ssh-pkcs11.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-pkcs11.c,v 1.62 2024/04/02 12:22:38 deraadt Exp $ */ +/* $OpenBSD: ssh-pkcs11.c,v 1.64 2024/09/20 02:00:46 jsg Exp $ */ /* * Copyright (c) 2010 Markus Friedl. All rights reserved. * Copyright (c) 2014 Pedro Martelletto. All rights reserved. @@ -502,8 +502,10 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } - RSA_set_method(rsa, rsa_method); - RSA_set_ex_data(rsa, rsa_idx, k11); + if (RSA_set_method(rsa, rsa_method) != 1) + fatal_f("RSA_set_method failed"); + if (RSA_set_ex_data(rsa, rsa_idx, k11) != 1) + fatal_f("RSA_set_ex_data failed"); return (0); } @@ -615,8 +617,10 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, k11->keyid = xmalloc(k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); } - EC_KEY_set_method(ec, ec_key_method); - EC_KEY_set_ex_data(ec, ec_key_idx, k11); + if (EC_KEY_set_method(ec, ec_key_method) != 1) + fatal_f("EC_KEY_set_method failed"); + if (EC_KEY_set_ex_data(ec, ec_key_idx, k11) != 1) + fatal_f("EC_KEY_set_ex_data failed"); return (0); } @@ -803,11 +807,14 @@ pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } - key->ecdsa = ec; + EVP_PKEY_free(key->pkey); + if ((key->pkey = EVP_PKEY_new()) == NULL) + fatal("EVP_PKEY_new failed"); + if (EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) + fatal("EVP_PKEY_set1_EC_KEY failed"); key->ecdsa_nid = nid; key->type = KEY_ECDSA; key->flags |= SSHKEY_FLAG_EXT; - ec = NULL; /* now owned by key */ fail: for (i = 0; i < 3; i++) @@ -899,10 +906,13 @@ pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto fail; } - key->rsa = rsa; + EVP_PKEY_free(key->pkey); + if ((key->pkey = EVP_PKEY_new()) == NULL) + fatal("EVP_PKEY_new failed"); + if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) + fatal("EVP_PKEY_set1_RSA failed"); key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; - rsa = NULL; /* now owned by key */ fail: for (i = 0; i < 3; i++) @@ -1014,10 +1024,13 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto out; } - key->rsa = rsa; + EVP_PKEY_free(key->pkey); + if ((key->pkey = EVP_PKEY_new()) == NULL) + fatal("EVP_PKEY_new failed"); + if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) + fatal("EVP_PKEY_set1_RSA failed"); key->type = KEY_RSA; key->flags |= SSHKEY_FLAG_EXT; - rsa = NULL; /* now owned by key */ #if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW) } else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) { if (EVP_PKEY_get0_EC_KEY(evp) == NULL) { @@ -1044,11 +1057,14 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx, goto out; } - key->ecdsa = ec; + EVP_PKEY_free(key->pkey); + if ((key->pkey = EVP_PKEY_new()) == NULL) + fatal("EVP_PKEY_new failed"); + if (EVP_PKEY_set1_EC_KEY(key->pkey, ec) != 1) + fatal("EVP_PKEY_set1_EC_KEY failed"); key->ecdsa_nid = nid; key->type = KEY_ECDSA; key->flags |= SSHKEY_FLAG_EXT; - ec = NULL; /* now owned by key */ #endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */ } else { error("unknown certificate key type"); @@ -1176,7 +1192,7 @@ pkcs11_fetch_certs(struct pkcs11_provider *p, CK_ULONG slotidx, } note_key(p, slotidx, __func__, key); if (pkcs11_key_included(keysp, nkeys, key)) { - debug2_f("key already included");; + debug2_f("key already included"); sshkey_free(key); } else { /* expand key array and add key */ @@ -1290,7 +1306,7 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx, } note_key(p, slotidx, __func__, key); if (pkcs11_key_included(keysp, nkeys, key)) { - debug2_f("key already included");; + debug2_f("key already included"); sshkey_free(key); } else { /* expand key array and add key */ diff --git a/ssh-rsa.c b/ssh-rsa.c index be8f51e7576..3ad1fddc4e1 100644 --- a/ssh-rsa.c +++ b/ssh-rsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-rsa.c,v 1.79 2023/03/05 05:34:09 dtucker Exp $ */ +/* $OpenBSD: ssh-rsa.c,v 1.80 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2000, 2003 Markus Friedl * @@ -36,23 +36,18 @@ #include "openbsd-compat/openssl-compat.h" -static int openssh_RSA_verify(int, u_char *, size_t, u_char *, size_t, RSA *); - static u_int -ssh_rsa_size(const struct sshkey *key) +ssh_rsa_size(const struct sshkey *k) { - const BIGNUM *rsa_n; - - if (key->rsa == NULL) + if (k->pkey == NULL) return 0; - RSA_get0_key(key->rsa, &rsa_n, NULL, NULL); - return BN_num_bits(rsa_n); + return EVP_PKEY_bits(k->pkey); } static int ssh_rsa_alloc(struct sshkey *k) { - if ((k->rsa = RSA_new()) == NULL) + if ((k->pkey = EVP_PKEY_new()) == NULL) return SSH_ERR_ALLOC_FAIL; return 0; } @@ -60,29 +55,16 @@ ssh_rsa_alloc(struct sshkey *k) static void ssh_rsa_cleanup(struct sshkey *k) { - RSA_free(k->rsa); - k->rsa = NULL; + EVP_PKEY_free(k->pkey); + k->pkey = NULL; } static int ssh_rsa_equal(const struct sshkey *a, const struct sshkey *b) { - const BIGNUM *rsa_e_a, *rsa_n_a; - const BIGNUM *rsa_e_b, *rsa_n_b; - - if (a->rsa == NULL || b->rsa == NULL) - return 0; - RSA_get0_key(a->rsa, &rsa_n_a, &rsa_e_a, NULL); - RSA_get0_key(b->rsa, &rsa_n_b, &rsa_e_b, NULL); - if (rsa_e_a == NULL || rsa_e_b == NULL) + if (a->pkey == NULL || b->pkey == NULL) return 0; - if (rsa_n_a == NULL || rsa_n_b == NULL) - return 0; - if (BN_cmp(rsa_e_a, rsa_e_b) != 0) - return 0; - if (BN_cmp(rsa_n_a, rsa_n_b) != 0) - return 0; - return 1; + return EVP_PKEY_cmp(a->pkey, b->pkey) == 1; } static int @@ -91,10 +73,14 @@ ssh_rsa_serialize_public(const struct sshkey *key, struct sshbuf *b, { int r; const BIGNUM *rsa_n, *rsa_e; + const RSA *rsa; - if (key->rsa == NULL) + if (key->pkey == NULL) return SSH_ERR_INVALID_ARGUMENT; - RSA_get0_key(key->rsa, &rsa_n, &rsa_e, NULL); + if ((rsa = EVP_PKEY_get0_RSA(key->pkey)) == NULL) + return SSH_ERR_LIBCRYPTO_ERROR; + + RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); if ((r = sshbuf_put_bignum2(b, rsa_e)) != 0 || (r = sshbuf_put_bignum2(b, rsa_n)) != 0) return r; @@ -108,10 +94,13 @@ ssh_rsa_serialize_private(const struct sshkey *key, struct sshbuf *b, { int r; const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q; + const RSA *rsa; - RSA_get0_key(key->rsa, &rsa_n, &rsa_e, &rsa_d); - RSA_get0_factors(key->rsa, &rsa_p, &rsa_q); - RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp); + if ((rsa = EVP_PKEY_get0_RSA(key->pkey)) == NULL) + return SSH_ERR_LIBCRYPTO_ERROR; + RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); + RSA_get0_factors(rsa, &rsa_p, &rsa_q); + RSA_get0_crt_params(rsa, NULL, NULL, &rsa_iqmp); if (!sshkey_is_cert(key)) { /* Note: can't reuse ssh_rsa_serialize_public: e, n vs. n, e */ @@ -131,28 +120,36 @@ ssh_rsa_serialize_private(const struct sshkey *key, struct sshbuf *b, static int ssh_rsa_generate(struct sshkey *k, int bits) { - RSA *private = NULL; - BIGNUM *f4 = NULL; + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *res = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE || bits > SSHBUF_MAX_BIGNUM * 8) return SSH_ERR_KEY_LENGTH; - if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) { + + if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) { ret = SSH_ERR_ALLOC_FAIL; goto out; } - if (!BN_set_word(f4, RSA_F4) || - !RSA_generate_key_ex(private, bits, f4, NULL)) { + if (EVP_PKEY_keygen_init(ctx) <= 0) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) { + ret = SSH_ERR_KEY_LENGTH; + goto out; + } + if (EVP_PKEY_keygen(ctx, &res) <= 0 || res == NULL) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - k->rsa = private; - private = NULL; + /* success */ + k->pkey = res; ret = 0; out: - RSA_free(private); - BN_free(f4); + EVP_PKEY_CTX_free(ctx); return ret; } @@ -162,21 +159,33 @@ ssh_rsa_copy_public(const struct sshkey *from, struct sshkey *to) const BIGNUM *rsa_n, *rsa_e; BIGNUM *rsa_n_dup = NULL, *rsa_e_dup = NULL; int r = SSH_ERR_INTERNAL_ERROR; + const RSA *rsa_from; + RSA *rsa_to = NULL; - RSA_get0_key(from->rsa, &rsa_n, &rsa_e, NULL); + if ((rsa_from = EVP_PKEY_get0_RSA(from->pkey)) == NULL || + (rsa_to = RSA_new()) == NULL) + return SSH_ERR_LIBCRYPTO_ERROR; + + RSA_get0_key(rsa_from, &rsa_n, &rsa_e, NULL); if ((rsa_n_dup = BN_dup(rsa_n)) == NULL || (rsa_e_dup = BN_dup(rsa_e)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } - if (!RSA_set0_key(to->rsa, rsa_n_dup, rsa_e_dup, NULL)) { + if (!RSA_set0_key(rsa_to, rsa_n_dup, rsa_e_dup, NULL)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } rsa_n_dup = rsa_e_dup = NULL; /* transferred */ + + if (EVP_PKEY_set1_RSA(to->pkey, rsa_to) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } /* success */ r = 0; out: + RSA_free(rsa_to); BN_clear_free(rsa_n_dup); BN_clear_free(rsa_e_dup); return r; @@ -188,25 +197,34 @@ ssh_rsa_deserialize_public(const char *ktype, struct sshbuf *b, { int ret = SSH_ERR_INTERNAL_ERROR; BIGNUM *rsa_n = NULL, *rsa_e = NULL; + RSA *rsa = NULL; + + if ((rsa = RSA_new()) == NULL) + return SSH_ERR_LIBCRYPTO_ERROR; if (sshbuf_get_bignum2(b, &rsa_e) != 0 || sshbuf_get_bignum2(b, &rsa_n) != 0) { ret = SSH_ERR_INVALID_FORMAT; goto out; } - if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) { + if (!RSA_set0_key(rsa, rsa_n, rsa_e, NULL)) { ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; } rsa_n = rsa_e = NULL; /* transferred */ + if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } if ((ret = sshkey_check_rsa_length(key, 0)) != 0) goto out; #ifdef DEBUG_PK - RSA_print_fp(stderr, key->rsa, 8); + RSA_print_fp(stderr, rsa, 8); #endif /* success */ ret = 0; out: + RSA_free(rsa); BN_clear_free(rsa_n); BN_clear_free(rsa_e); return ret; @@ -219,13 +237,25 @@ ssh_rsa_deserialize_private(const char *ktype, struct sshbuf *b, int r; BIGNUM *rsa_n = NULL, *rsa_e = NULL, *rsa_d = NULL; BIGNUM *rsa_iqmp = NULL, *rsa_p = NULL, *rsa_q = NULL; + BIGNUM *rsa_dmp1 = NULL, *rsa_dmq1 = NULL; + RSA *rsa = NULL; - /* Note: can't reuse ssh_rsa_deserialize_public: e, n vs. n, e */ - if (!sshkey_is_cert(key)) { + if (sshkey_is_cert(key)) { + /* sshkey_private_deserialize already has pubkey from cert */ + if ((rsa = EVP_PKEY_get1_RSA(key->pkey)) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + } else { + if ((rsa = RSA_new()) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + /* Note: can't reuse ssh_rsa_deserialize_public: e,n vs. n,e */ if ((r = sshbuf_get_bignum2(b, &rsa_n)) != 0 || (r = sshbuf_get_bignum2(b, &rsa_e)) != 0) goto out; - if (!RSA_set0_key(key->rsa, rsa_n, rsa_e, NULL)) { + if (!RSA_set0_key(rsa, rsa_n, rsa_e, NULL)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } @@ -236,33 +266,46 @@ ssh_rsa_deserialize_private(const char *ktype, struct sshbuf *b, (r = sshbuf_get_bignum2(b, &rsa_p)) != 0 || (r = sshbuf_get_bignum2(b, &rsa_q)) != 0) goto out; - if (!RSA_set0_key(key->rsa, NULL, NULL, rsa_d)) { + if ((r = ssh_rsa_complete_crt_parameters(rsa_d, rsa_p, rsa_q, + rsa_iqmp, &rsa_dmp1, &rsa_dmq1)) != 0) + goto out; + if (!RSA_set0_key(rsa, NULL, NULL, rsa_d)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } rsa_d = NULL; /* transferred */ - if (!RSA_set0_factors(key->rsa, rsa_p, rsa_q)) { + if (!RSA_set0_factors(rsa, rsa_p, rsa_q)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } rsa_p = rsa_q = NULL; /* transferred */ - if ((r = sshkey_check_rsa_length(key, 0)) != 0) + if (!RSA_set0_crt_params(rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) { + r = SSH_ERR_LIBCRYPTO_ERROR; goto out; - if ((r = ssh_rsa_complete_crt_parameters(key, rsa_iqmp)) != 0) + } + rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; + if (RSA_blinding_on(rsa, NULL) != 1) { + r = SSH_ERR_LIBCRYPTO_ERROR; goto out; - if (RSA_blinding_on(key->rsa, NULL) != 1) { + } + if (EVP_PKEY_set1_RSA(key->pkey, rsa) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } + if ((r = sshkey_check_rsa_length(key, 0)) != 0) + goto out; /* success */ r = 0; out: + RSA_free(rsa); BN_clear_free(rsa_n); BN_clear_free(rsa_e); BN_clear_free(rsa_d); BN_clear_free(rsa_p); BN_clear_free(rsa_q); BN_clear_free(rsa_iqmp); + BN_clear_free(rsa_dmp1); + BN_clear_free(rsa_dmq1); return r; } @@ -317,45 +360,23 @@ rsa_hash_id_from_keyname(const char *alg) return -1; } -static int -rsa_hash_alg_nid(int type) -{ - switch (type) { - case SSH_DIGEST_SHA1: - return NID_sha1; - case SSH_DIGEST_SHA256: - return NID_sha256; - case SSH_DIGEST_SHA512: - return NID_sha512; - default: - return -1; - } -} - int -ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp) +ssh_rsa_complete_crt_parameters(const BIGNUM *rsa_d, const BIGNUM *rsa_p, + const BIGNUM *rsa_q, const BIGNUM *rsa_iqmp, BIGNUM **rsa_dmp1, + BIGNUM **rsa_dmq1) { - const BIGNUM *rsa_p, *rsa_q, *rsa_d; BIGNUM *aux = NULL, *d_consttime = NULL; - BIGNUM *rsa_dmq1 = NULL, *rsa_dmp1 = NULL, *rsa_iqmp = NULL; BN_CTX *ctx = NULL; int r; - if (key == NULL || key->rsa == NULL || - sshkey_type_plain(key->type) != KEY_RSA) - return SSH_ERR_INVALID_ARGUMENT; - - RSA_get0_key(key->rsa, NULL, NULL, &rsa_d); - RSA_get0_factors(key->rsa, &rsa_p, &rsa_q); - + *rsa_dmq1 = *rsa_dmp1 = NULL; if ((ctx = BN_CTX_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((aux = BN_new()) == NULL || - (rsa_dmq1 = BN_new()) == NULL || - (rsa_dmp1 = BN_new()) == NULL) + (*rsa_dmq1 = BN_new()) == NULL || + (*rsa_dmp1 = BN_new()) == NULL) return SSH_ERR_ALLOC_FAIL; - if ((d_consttime = BN_dup(rsa_d)) == NULL || - (rsa_iqmp = BN_dup(iqmp)) == NULL) { + if ((d_consttime = BN_dup(rsa_d)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } @@ -363,25 +384,17 @@ ssh_rsa_complete_crt_parameters(struct sshkey *key, const BIGNUM *iqmp) BN_set_flags(d_consttime, BN_FLG_CONSTTIME); if ((BN_sub(aux, rsa_q, BN_value_one()) == 0) || - (BN_mod(rsa_dmq1, d_consttime, aux, ctx) == 0) || + (BN_mod(*rsa_dmq1, d_consttime, aux, ctx) == 0) || (BN_sub(aux, rsa_p, BN_value_one()) == 0) || - (BN_mod(rsa_dmp1, d_consttime, aux, ctx) == 0)) { + (BN_mod(*rsa_dmp1, d_consttime, aux, ctx) == 0)) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } - if (!RSA_set0_crt_params(key->rsa, rsa_dmp1, rsa_dmq1, rsa_iqmp)) { - r = SSH_ERR_LIBCRYPTO_ERROR; - goto out; - } - rsa_dmp1 = rsa_dmq1 = rsa_iqmp = NULL; /* transferred */ /* success */ r = 0; out: BN_clear_free(aux); BN_clear_free(d_consttime); - BN_clear_free(rsa_dmp1); - BN_clear_free(rsa_dmq1); - BN_clear_free(rsa_iqmp); BN_CTX_free(ctx); return r; } @@ -393,11 +406,10 @@ ssh_rsa_sign(struct sshkey *key, const u_char *data, size_t datalen, const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { - const BIGNUM *rsa_n; - u_char digest[SSH_DIGEST_MAX_LENGTH], *sig = NULL; - size_t slen = 0; - u_int hlen, len; - int nid, hash_alg, ret = SSH_ERR_INTERNAL_ERROR; + u_char *sig = NULL; + size_t diff, len = 0; + int slen = 0; + int hash_alg, ret = SSH_ERR_INTERNAL_ERROR; struct sshbuf *b = NULL; if (lenp != NULL) @@ -409,41 +421,28 @@ ssh_rsa_sign(struct sshkey *key, hash_alg = SSH_DIGEST_SHA1; else hash_alg = rsa_hash_id_from_keyname(alg); - if (key == NULL || key->rsa == NULL || hash_alg == -1 || + + if (key == NULL || key->pkey == NULL || hash_alg == -1 || sshkey_type_plain(key->type) != KEY_RSA) return SSH_ERR_INVALID_ARGUMENT; - RSA_get0_key(key->rsa, &rsa_n, NULL, NULL); - if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE) - return SSH_ERR_KEY_LENGTH; - slen = RSA_size(key->rsa); + slen = EVP_PKEY_size(key->pkey); if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) return SSH_ERR_INVALID_ARGUMENT; + if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE) + return SSH_ERR_KEY_LENGTH; - /* hash the data */ - nid = rsa_hash_alg_nid(hash_alg); - if ((hlen = ssh_digest_bytes(hash_alg)) == 0) - return SSH_ERR_INTERNAL_ERROR; - if ((ret = ssh_digest_memory(hash_alg, data, datalen, - digest, sizeof(digest))) != 0) - goto out; - - if ((sig = malloc(slen)) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto out; - } - - if (RSA_sign(nid, digest, hlen, sig, &len, key->rsa) != 1) { - ret = SSH_ERR_LIBCRYPTO_ERROR; + if ((ret = sshkey_pkey_digest_sign(key->pkey, hash_alg, &sig, &len, + data, datalen)) < 0) goto out; - } - if (len < slen) { - size_t diff = slen - len; + if (len < (size_t)slen) { + diff = slen - len; memmove(sig + diff, sig, len); explicit_bzero(sig, diff); - } else if (len > slen) { + } else if (len > (size_t)slen) { ret = SSH_ERR_INTERNAL_ERROR; goto out; } + /* encode signature */ if ((b = sshbuf_new()) == NULL) { ret = SSH_ERR_ALLOC_FAIL; @@ -464,7 +463,6 @@ ssh_rsa_sign(struct sshkey *key, *lenp = len; ret = 0; out: - explicit_bzero(digest, sizeof(digest)); freezero(sig, slen); sshbuf_free(b); return ret; @@ -476,19 +474,17 @@ ssh_rsa_verify(const struct sshkey *key, const u_char *data, size_t dlen, const char *alg, u_int compat, struct sshkey_sig_details **detailsp) { - const BIGNUM *rsa_n; char *sigtype = NULL; int hash_alg, want_alg, ret = SSH_ERR_INTERNAL_ERROR; - size_t len = 0, diff, modlen, hlen; + size_t len = 0, diff, modlen, rsasize; struct sshbuf *b = NULL; u_char digest[SSH_DIGEST_MAX_LENGTH], *osigblob, *sigblob = NULL; - if (key == NULL || key->rsa == NULL || + if (key == NULL || key->pkey == NULL || sshkey_type_plain(key->type) != KEY_RSA || sig == NULL || siglen == 0) return SSH_ERR_INVALID_ARGUMENT; - RSA_get0_key(key->rsa, &rsa_n, NULL, NULL); - if (BN_num_bits(rsa_n) < SSH_RSA_MINIMUM_MODULUS_SIZE) + if (EVP_PKEY_bits(key->pkey) < SSH_RSA_MINIMUM_MODULUS_SIZE) return SSH_ERR_KEY_LENGTH; if ((b = sshbuf_from(sig, siglen)) == NULL) @@ -524,7 +520,7 @@ ssh_rsa_verify(const struct sshkey *key, goto out; } /* RSA_verify expects a signature of RSA_size */ - modlen = RSA_size(key->rsa); + modlen = EVP_PKEY_size(key->pkey); if (len > modlen) { ret = SSH_ERR_KEY_BITS_MISMATCH; goto out; @@ -540,16 +536,16 @@ ssh_rsa_verify(const struct sshkey *key, explicit_bzero(sigblob, diff); len = modlen; } - if ((hlen = ssh_digest_bytes(hash_alg)) == 0) { - ret = SSH_ERR_INTERNAL_ERROR; + + rsasize = EVP_PKEY_size(key->pkey); + if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || + len == 0 || len > rsasize) { + ret = SSH_ERR_INVALID_ARGUMENT; goto out; } - if ((ret = ssh_digest_memory(hash_alg, data, dlen, - digest, sizeof(digest))) != 0) - goto out; + ret = sshkey_pkey_digest_verify(key->pkey, hash_alg, data, dlen, + sigblob, len); - ret = openssh_RSA_verify(hash_alg, digest, hlen, sigblob, len, - key->rsa); out: freezero(sigblob, len); free(sigtype); @@ -558,125 +554,6 @@ ssh_rsa_verify(const struct sshkey *key, return ret; } -/* - * See: - * http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/ - * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.asn - */ - -/* - * id-sha1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) - * oiw(14) secsig(3) algorithms(2) 26 } - */ -static const u_char id_sha1[] = { - 0x30, 0x21, /* type Sequence, length 0x21 (33) */ - 0x30, 0x09, /* type Sequence, length 0x09 */ - 0x06, 0x05, /* type OID, length 0x05 */ - 0x2b, 0x0e, 0x03, 0x02, 0x1a, /* id-sha1 OID */ - 0x05, 0x00, /* NULL */ - 0x04, 0x14 /* Octet string, length 0x14 (20), followed by sha1 hash */ -}; - -/* - * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html - * id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) - * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) - * id-sha256(1) } - */ -static const u_char id_sha256[] = { - 0x30, 0x31, /* type Sequence, length 0x31 (49) */ - 0x30, 0x0d, /* type Sequence, length 0x0d (13) */ - 0x06, 0x09, /* type OID, length 0x09 */ - 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, /* id-sha256 */ - 0x05, 0x00, /* NULL */ - 0x04, 0x20 /* Octet string, length 0x20 (32), followed by sha256 hash */ -}; - -/* - * See http://csrc.nist.gov/groups/ST/crypto_apps_infra/csor/algorithms.html - * id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) country(16) us(840) - * organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) - * id-sha256(3) } - */ -static const u_char id_sha512[] = { - 0x30, 0x51, /* type Sequence, length 0x51 (81) */ - 0x30, 0x0d, /* type Sequence, length 0x0d (13) */ - 0x06, 0x09, /* type OID, length 0x09 */ - 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, /* id-sha512 */ - 0x05, 0x00, /* NULL */ - 0x04, 0x40 /* Octet string, length 0x40 (64), followed by sha512 hash */ -}; - -static int -rsa_hash_alg_oid(int hash_alg, const u_char **oidp, size_t *oidlenp) -{ - switch (hash_alg) { - case SSH_DIGEST_SHA1: - *oidp = id_sha1; - *oidlenp = sizeof(id_sha1); - break; - case SSH_DIGEST_SHA256: - *oidp = id_sha256; - *oidlenp = sizeof(id_sha256); - break; - case SSH_DIGEST_SHA512: - *oidp = id_sha512; - *oidlenp = sizeof(id_sha512); - break; - default: - return SSH_ERR_INVALID_ARGUMENT; - } - return 0; -} - -static int -openssh_RSA_verify(int hash_alg, u_char *hash, size_t hashlen, - u_char *sigbuf, size_t siglen, RSA *rsa) -{ - size_t rsasize = 0, oidlen = 0, hlen = 0; - int ret, len, oidmatch, hashmatch; - const u_char *oid = NULL; - u_char *decrypted = NULL; - - if ((ret = rsa_hash_alg_oid(hash_alg, &oid, &oidlen)) != 0) - return ret; - ret = SSH_ERR_INTERNAL_ERROR; - hlen = ssh_digest_bytes(hash_alg); - if (hashlen != hlen) { - ret = SSH_ERR_INVALID_ARGUMENT; - goto done; - } - rsasize = RSA_size(rsa); - if (rsasize <= 0 || rsasize > SSHBUF_MAX_BIGNUM || - siglen == 0 || siglen > rsasize) { - ret = SSH_ERR_INVALID_ARGUMENT; - goto done; - } - if ((decrypted = malloc(rsasize)) == NULL) { - ret = SSH_ERR_ALLOC_FAIL; - goto done; - } - if ((len = RSA_public_decrypt(siglen, sigbuf, decrypted, rsa, - RSA_PKCS1_PADDING)) < 0) { - ret = SSH_ERR_LIBCRYPTO_ERROR; - goto done; - } - if (len < 0 || (size_t)len != hlen + oidlen) { - ret = SSH_ERR_INVALID_FORMAT; - goto done; - } - oidmatch = timingsafe_bcmp(decrypted, oid, oidlen) == 0; - hashmatch = timingsafe_bcmp(decrypted + oidlen, hash, hlen) == 0; - if (!oidmatch || !hashmatch) { - ret = SSH_ERR_SIGNATURE_INVALID; - goto done; - } - ret = 0; -done: - freezero(decrypted, rsasize); - return ret; -} - static const struct sshkey_impl_funcs sshkey_rsa_funcs = { /* .size = */ ssh_rsa_size, /* .alloc = */ ssh_rsa_alloc, diff --git a/ssh-sandbox.h b/ssh-sandbox.h index bd5fd83722a..3b74840266b 100644 --- a/ssh-sandbox.h +++ b/ssh-sandbox.h @@ -20,5 +20,3 @@ struct ssh_sandbox; struct ssh_sandbox *ssh_sandbox_init(struct monitor *); void ssh_sandbox_child(struct ssh_sandbox *); -void ssh_sandbox_parent_finish(struct ssh_sandbox *); -void ssh_sandbox_parent_preauth(struct ssh_sandbox *, pid_t); diff --git a/ssh-sk-helper.0 b/ssh-sk-helper.0 index ea2117abd13..9dc341c35b6 100644 --- a/ssh-sk-helper.0 +++ b/ssh-sk-helper.0 @@ -31,4 +31,4 @@ HISTORY AUTHORS Damien Miller -OpenBSD 7.5 April 29, 2022 OpenBSD 7.5 +OpenBSD 7.6 April 29, 2022 OpenBSD 7.6 diff --git a/ssh-sk.c b/ssh-sk.c index 00bb5644339..c1739c87696 100644 --- a/ssh-sk.c +++ b/ssh-sk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-sk.c,v 1.40 2023/07/19 14:02:27 djm Exp $ */ +/* $OpenBSD: ssh-sk.c,v 1.41 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2019 Google LLC * @@ -32,6 +32,7 @@ #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) #include #include +#include #endif /* WITH_OPENSSL && OPENSSL_HAS_ECC */ #include "log.h" @@ -214,7 +215,9 @@ sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp) { struct sshkey *key = NULL; struct sshbuf *b = NULL; + EC_KEY *ecdsa = NULL; EC_POINT *q = NULL; + const EC_GROUP *g = NULL; int r; *keyp = NULL; @@ -224,8 +227,9 @@ sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp) goto out; } key->ecdsa_nid = NID_X9_62_prime256v1; - if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL || - (q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL || + if ((ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL || + (g = EC_KEY_get0_group(ecdsa)) == NULL || + (q = EC_POINT_new(g)) == NULL || (b = sshbuf_new()) == NULL) { error_f("allocation failed"); r = SSH_ERR_ALLOC_FAIL; @@ -236,30 +240,41 @@ sshsk_ecdsa_assemble(struct sk_enroll_response *resp, struct sshkey **keyp) error_fr(r, "sshbuf_put_string"); goto out; } - if ((r = sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa))) != 0) { + if ((r = sshbuf_get_ec(b, q, g)) != 0) { error_fr(r, "parse"); r = SSH_ERR_INVALID_FORMAT; goto out; } - if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), q) != 0) { + if (sshkey_ec_validate_public(g, q) != 0) { error("Authenticator returned invalid ECDSA key"); r = SSH_ERR_KEY_INVALID_EC_VALUE; goto out; } - if (EC_KEY_set_public_key(key->ecdsa, q) != 1) { + if (EC_KEY_set_public_key(ecdsa, q) != 1) { /* XXX assume it is a allocation error */ error_f("allocation failed"); r = SSH_ERR_ALLOC_FAIL; goto out; } + if ((key->pkey = EVP_PKEY_new()) == NULL) { + error_f("allocation failed"); + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (EVP_PKEY_set1_EC_KEY(key->pkey, ecdsa) != 1) { + error_f("Assigning EC_KEY failed"); + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } /* success */ *keyp = key; key = NULL; /* transferred */ r = 0; out: - EC_POINT_free(q); sshkey_free(key); sshbuf_free(b); + EC_KEY_free(ecdsa); + EC_POINT_free(q); return r; } #endif /* WITH_OPENSSL */ diff --git a/ssh.0 b/ssh.0 index 78863b1b0b2..7c8cf82e2d0 100644 --- a/ssh.0 +++ b/ssh.0 @@ -234,7 +234,8 @@ DESCRIPTION and passed to the master process. Valid commands are: M-bM-^@M-^\checkM-bM-^@M-^] (check that the master process is running), M-bM-^@M-^\forwardM-bM-^@M-^] (request forwardings without command execution), M-bM-^@M-^\cancelM-bM-^@M-^] (cancel - forwardings), M-bM-^@M-^\exitM-bM-^@M-^] (request the master to exit), and M-bM-^@M-^\stopM-bM-^@M-^] + forwardings), M-bM-^@M-^\proxyM-bM-^@M-^] (connect to a running multiplexing master + in proxy mode), M-bM-^@M-^\exitM-bM-^@M-^] (request the master to exit), and M-bM-^@M-^\stopM-bM-^@M-^] (request the master to stop accepting further multiplexing requests). @@ -249,24 +250,27 @@ DESCRIPTION AddressFamily BatchMode BindAddress + BindInterface + CASignatureAlgorithms CanonicalDomains CanonicalizeFallbackLocal CanonicalizeHostname CanonicalizeMaxDots CanonicalizePermittedCNAMEs - CASignatureAlgorithms CertificateFile + ChannelTimeout CheckHostIP Ciphers ClearAllForwardings Compression - ConnectionAttempts ConnectTimeout + ConnectionAttempts ControlMaster ControlPath ControlPersist DynamicForward EnableEscapeCommandline + EnableSSHKeysign EscapeChar ExitOnForwardFailure FingerprintHash @@ -275,21 +279,23 @@ DESCRIPTION ForwardX11 ForwardX11Timeout ForwardX11Trusted - GatewayPorts - GlobalKnownHostsFile GSSAPIAuthentication GSSAPIDelegateCredentials + GatewayPorts + GlobalKnownHostsFile HashKnownHosts Host - HostbasedAcceptedAlgorithms - HostbasedAuthentication HostKeyAlgorithms HostKeyAlias + HostbasedAcceptedAlgorithms + HostbasedAuthentication Hostname + IPQoS IdentitiesOnly IdentityAgent IdentityFile - IPQoS + IgnoreUnknown + Include KbdInteractiveAuthentication KbdInteractiveDevices KexAlgorithms @@ -297,14 +303,15 @@ DESCRIPTION LocalCommand LocalForward LogLevel + LogVerbose MACs - Match NoHostAuthenticationForLocalhost NumberOfPasswordPrompts + ObscureKeystrokeTiming + PKCS11Provider PasswordAuthentication PermitLocalCommand PermitRemoteOpen - PKCS11Provider Port PreferredAuthentications ProxyCommand @@ -317,16 +324,20 @@ DESCRIPTION RemoteForward RequestTTY RequiredRSASize + RevokedHostKeys + SecurityKeyProvider SendEnv - ServerAliveInterval ServerAliveCountMax + ServerAliveInterval SessionType SetEnv StdinNull StreamLocalBindMask StreamLocalBindUnlink StrictHostKeyChecking + SyslogFacility TCPKeepAlive + Tag Tunnel TunnelDevice UpdateHostKeys @@ -1016,4 +1027,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.5 June 27, 2024 OpenBSD 7.5 +OpenBSD 7.6 December 4, 2024 OpenBSD 7.6 diff --git a/ssh.1 b/ssh.1 index f871ff4e46a..697f4e42a4a 100644 --- a/ssh.1 +++ b/ssh.1 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.442 2024/06/27 21:02:16 jmc Exp $ -.Dd $Mdocdate: June 27 2024 $ +.\" $OpenBSD: ssh.1,v 1.444 2024/12/04 14:37:55 djm Exp $ +.Dd $Mdocdate: December 4 2024 $ .Dt SSH 1 .Os .Sh NAME @@ -490,6 +490,8 @@ Valid commands are: (request forwardings without command execution), .Dq cancel (cancel forwardings), +.Dq proxy +(connect to a running multiplexing master in proxy mode), .Dq exit (request the master to exit), and .Dq stop @@ -507,24 +509,27 @@ For full details of the options listed below, and their possible values, see .It AddressFamily .It BatchMode .It BindAddress +.It BindInterface +.It CASignatureAlgorithms .It CanonicalDomains .It CanonicalizeFallbackLocal .It CanonicalizeHostname .It CanonicalizeMaxDots .It CanonicalizePermittedCNAMEs -.It CASignatureAlgorithms .It CertificateFile +.It ChannelTimeout .It CheckHostIP .It Ciphers .It ClearAllForwardings .It Compression -.It ConnectionAttempts .It ConnectTimeout +.It ConnectionAttempts .It ControlMaster .It ControlPath .It ControlPersist .It DynamicForward .It EnableEscapeCommandline +.It EnableSSHKeysign .It EscapeChar .It ExitOnForwardFailure .It FingerprintHash @@ -533,21 +538,23 @@ For full details of the options listed below, and their possible values, see .It ForwardX11 .It ForwardX11Timeout .It ForwardX11Trusted -.It GatewayPorts -.It GlobalKnownHostsFile .It GSSAPIAuthentication .It GSSAPIDelegateCredentials +.It GatewayPorts +.It GlobalKnownHostsFile .It HashKnownHosts .It Host -.It HostbasedAcceptedAlgorithms -.It HostbasedAuthentication .It HostKeyAlgorithms .It HostKeyAlias +.It HostbasedAcceptedAlgorithms +.It HostbasedAuthentication .It Hostname +.It IPQoS .It IdentitiesOnly .It IdentityAgent .It IdentityFile -.It IPQoS +.It IgnoreUnknown +.It Include .It KbdInteractiveAuthentication .It KbdInteractiveDevices .It KexAlgorithms @@ -555,14 +562,15 @@ For full details of the options listed below, and their possible values, see .It LocalCommand .It LocalForward .It LogLevel +.It LogVerbose .It MACs -.It Match .It NoHostAuthenticationForLocalhost .It NumberOfPasswordPrompts +.It ObscureKeystrokeTiming +.It PKCS11Provider .It PasswordAuthentication .It PermitLocalCommand .It PermitRemoteOpen -.It PKCS11Provider .It Port .It PreferredAuthentications .It ProxyCommand @@ -575,16 +583,20 @@ For full details of the options listed below, and their possible values, see .It RemoteForward .It RequestTTY .It RequiredRSASize +.It RevokedHostKeys +.It SecurityKeyProvider .It SendEnv -.It ServerAliveInterval .It ServerAliveCountMax +.It ServerAliveInterval .It SessionType .It SetEnv .It StdinNull .It StreamLocalBindMask .It StreamLocalBindUnlink .It StrictHostKeyChecking +.It SyslogFacility .It TCPKeepAlive +.It Tag .It Tunnel .It TunnelDevice .It UpdateHostKeys diff --git a/ssh.c b/ssh.c index 9793359b346..ea94d25106c 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.600 2024/01/11 01:45:36 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.612 2025/04/09 01:24:40 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -50,6 +50,9 @@ #include #include #include +#ifndef WINDOWS +#include +#endif /* WINDOWS */ #include #include @@ -558,15 +561,18 @@ check_load(int r, struct sshkey **k, const char *path, const char *message) * file if the user specifies a config file on the command line. */ static void -process_config_files(const char *host_name, struct passwd *pw, int final_pass, - int *want_final_pass) +process_config_files(const char *host_name, struct passwd *pw, + int final_pass, int *want_final_pass) { - char buf[PATH_MAX]; + char *cmd, buf[PATH_MAX]; int r; + if ((cmd = sshbuf_dup_string(command)) == NULL) + fatal_f("sshbuf_dup_string failed"); if (config != NULL) { if (strcasecmp(config, "none") != 0 && - !read_config_file(config, pw, host, host_name, &options, + !read_config_file(config, pw, host, host_name, cmd, + &options, SSHCONF_USERCONF | (final_pass ? SSHCONF_FINAL : 0), want_final_pass)) fatal("Can't open user config file %.100s: " @@ -575,7 +581,7 @@ process_config_files(const char *host_name, struct passwd *pw, int final_pass, r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, _PATH_SSH_USER_CONFFILE); if (r > 0 && (size_t)r < sizeof(buf)) - (void)read_config_file(buf, pw, host, host_name, + (void)read_config_file(buf, pw, host, host_name, cmd, &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | (final_pass ? SSHCONF_FINAL : 0), want_final_pass); @@ -587,14 +593,15 @@ process_config_files(const char *host_name, struct passwd *pw, int final_pass, * This is not desirable. For windows, We make sure the systemwide sshd_config file is not editable by non-admin users. */ (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, - host, host_name, &options, SSHCONF_CHECKPERM | + host, host_name, cmd, &options, SSHCONF_CHECKPERM | (final_pass ? SSHCONF_FINAL : 0), want_final_pass); #else (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, - host, host_name, &options, + host, host_name, cmd, &options, final_pass ? SSHCONF_FINAL : 0, want_final_pass); #endif } + free(cmd); } /* Rewrite the port number in an addrinfo list of addresses */ @@ -645,7 +652,7 @@ valid_hostname(const char *s) if (*s == '-') return 0; for (i = 0; s[i] != 0; i++) { - if (strchr("'`\"$\\;&<>|(){}", s[i]) != NULL || + if (strchr("'`\"$\\;&<>|(){},", s[i]) != NULL || isspace((u_char)s[i]) || iscntrl((u_char)s[i])) return 0; } @@ -681,7 +688,7 @@ main(int ac, char **av) struct ssh *ssh = NULL; int i, r, opt, exit_status, use_syslog, direct, timeout_ms; int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0; - char *p, *cp, *line, *argv0, *logfile; + char *p, *cp, *line, *argv0, *logfile, *args; char cname[NI_MAXHOST], thishost[NI_MAXHOST]; struct stat st; struct passwd *pw; @@ -691,6 +698,9 @@ main(int ac, char **av) struct addrinfo *addrs = NULL; size_t n, len; u_int j; +#ifndef WINDOWS + struct utsname utsname; +#endif /* WINDOWS */ struct ssh_conn_info *cinfo = NULL; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ @@ -749,7 +759,9 @@ main(int ac, char **av) fatal("Couldn't allocate session state"); channel_init_channels(ssh); + /* Parse command-line arguments. */ + args = argv_assemble(ac, av); /* logged later */ host = NULL; use_syslog = 0; logfile = NULL; @@ -976,7 +988,7 @@ main(int ac, char **av) options.log_level = SYSLOG_LEVEL_QUIET; break; case 'e': - if (optarg[0] == '^' && optarg[2] == 0 && + if (strlen(optarg) == 2 && optarg[0] == '^' && (u_char) optarg[1] >= 64 && (u_char) optarg[1] < 128) options.escape_char = (u_char) optarg[1] & 31; @@ -1028,7 +1040,7 @@ main(int ac, char **av) break; case 'l': if (options.user == NULL) - options.user = optarg; + options.user = xstrdup(optarg); break; case 'L': @@ -1085,7 +1097,7 @@ main(int ac, char **av) case 'o': line = xstrdup(optarg); if (process_config_line(&options, pw, - host ? host : "", host ? host : "", line, + host ? host : "", host ? host : "", "", line, "command-line", 0, NULL, SSHCONF_USERCONF) != 0) exit(255); free(line); @@ -1166,8 +1178,6 @@ main(int ac, char **av) if (!valid_hostname(host)) fatal("hostname contains invalid characters"); - if (options.user != NULL && !valid_ruser(options.user)) - fatal("remote username contains invalid characters"); options.host_arg = xstrdup(host); /* Initialize the command to execute on remote host. */ @@ -1212,8 +1222,17 @@ main(int ac, char **av) SYSLOG_FACILITY_USER : options.log_facility, !use_syslog); - if (debug_flag) - logit("%s, %s", SSH_RELEASE, SSH_OPENSSL_VERSION); + debug("%s, %s", SSH_RELEASE, SSH_OPENSSL_VERSION); +#ifndef WINDOWS + if (uname(&utsname) != 0) { + memset(&utsname, 0, sizeof(utsname)); + strlcpy(utsname.sysname, "UNKNOWN", sizeof(utsname.sysname)); + } + debug3("Running on %s %s %s %s", utsname.sysname, utsname.release, + utsname.version, utsname.machine); +#endif /* WINDOWS */ + debug3("Started with: %s", args); + free(args); /* Parse the configuration files */ process_config_files(options.host_arg, pw, 0, &want_final_pass); @@ -1447,11 +1466,28 @@ main(int ac, char **av) options.host_key_alias : options.host_arg); cinfo->host_arg = xstrdup(options.host_arg); cinfo->remhost = xstrdup(host); - cinfo->remuser = xstrdup(options.user); cinfo->homedir = xstrdup(pw->pw_dir); cinfo->locuser = xstrdup(pw->pw_name); cinfo->jmphost = xstrdup(options.jump_host == NULL ? "" : options.jump_host); + + /* + * Expand User. It cannot contain %r (itself) or %C since User is + * a component of the hash. + */ + if (options.user != NULL) { + if ((p = percent_dollar_expand(options.user, + DEFAULT_CLIENT_PERCENT_EXPAND_ARGS_NOUSER(cinfo), + (char *)NULL)) == NULL) + fatal("invalid environment variable expansion"); + free(options.user); + options.user = p; + if (!valid_ruser(options.user)) + fatal("remote username contains invalid characters"); + } + + /* Now User is expanded, store it and calculate hash. */ + cinfo->remuser = xstrdup(options.user); cinfo->conn_hash_hex = ssh_connection_hash(cinfo->thishost, cinfo->remhost, cinfo->portstr, cinfo->remuser, cinfo->jmphost); @@ -1511,6 +1547,13 @@ main(int ac, char **av) } } + if (options.version_addendum != NULL) { + cp = default_client_percent_dollar_expand( + options.version_addendum, cinfo); + free(options.version_addendum); + options.version_addendum = cp; + } + if (options.num_system_hostfiles > 0 && strcasecmp(options.system_hostfiles[0], "none") == 0) { if (options.num_system_hostfiles > 1) @@ -1543,6 +1586,28 @@ main(int ac, char **av) options.user_hostfiles[j] = p; } + for (j = 0; j < options.num_setenv; j++) { + char *name = options.setenv[j], *value; + + if (name == NULL) + continue; + /* Expand only the value portion, not the variable name. */ + if ((value = strchr(name, '=')) == NULL) { + /* shouldn't happen; vars are checked in readconf.c */ + fatal("Invalid config SetEnv: %s", name); + } + *value++ = '\0'; + cp = default_client_percent_dollar_expand(value, cinfo); + xasprintf(&p, "%s=%s", name, cp); + if (strcmp(value, p) != 0) { + debug3("expanded SetEnv '%s' '%s' -> '%s'", + name, value, cp); + } + free(options.setenv[j]); + free(cp); + options.setenv[j] = p; + } + for (i = 0; i < options.num_local_forwards; i++) { if (options.local_forwards[i].listen_path != NULL) { cp = options.local_forwards[i].listen_path; diff --git a/ssh.h b/ssh.h index 8110c060287..cd95dd831f9 100644 --- a/ssh.h +++ b/ssh.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.h,v 1.90 2020/07/14 23:57:01 djm Exp $ */ +/* $OpenBSD: ssh.h,v 1.91 2024/09/25 23:01:39 jsg Exp $ */ /* * Author: Tatu Ylonen @@ -12,9 +12,6 @@ * called by a name other than "ssh" or "Secure Shell". */ -/* Cipher used for encrypting authentication files. */ -#define SSH_AUTHFILE_CIPHER SSH_CIPHER_3DES - /* Default port number. */ #define SSH_DEFAULT_PORT 22 @@ -36,11 +33,9 @@ * * Minor protocol version. Different version indicates minor incompatibility * that does not prevent interoperation. + * + * We support only SSH2 */ -#define PROTOCOL_MAJOR_1 1 -#define PROTOCOL_MINOR_1 5 - -/* We support only SSH2 */ #define PROTOCOL_MAJOR_2 2 #define PROTOCOL_MINOR_2 0 @@ -72,12 +67,6 @@ */ #define SSH_ASKPASS_REQUIRE_ENV "SSH_ASKPASS_REQUIRE" -/* - * Force host key length and server key length to differ by at least this - * many bits. This is to make double encryption with rsaref work. - */ -#define SSH_KEY_BITS_RESERVED 128 - /* * Length of the session key in bytes. (Specified as 256 bits in the * protocol.) diff --git a/ssh_api.c b/ssh_api.c index 188e4ac3431..2118d763f4c 100644 --- a/ssh_api.c +++ b/ssh_api.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh_api.c,v 1.29 2024/05/17 00:30:24 djm Exp $ */ +/* $OpenBSD: ssh_api.c,v 1.32 2024/10/18 05:14:51 djm Exp $ */ /* * Copyright (c) 2012 Markus Friedl. All rights reserved. * @@ -134,6 +134,7 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) #endif /* WITH_OPENSSL */ ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_server; ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; + ssh->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; ssh->kex->load_host_public_key=&_ssh_host_public_key; ssh->kex->load_host_private_key=&_ssh_host_private_key; ssh->kex->sign=&_ssh_host_key_sign; @@ -152,6 +153,7 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) #endif /* WITH_OPENSSL */ ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client; + ssh->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_client; ssh->kex->verify_host_key =&_ssh_verify_host_key; } *sshp = ssh; @@ -533,7 +535,7 @@ _ssh_order_hostkeyalgs(struct ssh *ssh) char *orig, *avail, *oavail = NULL, *alg, *replace = NULL; char **proposal; size_t maxlen; - int ktype, r; + int ktype, nid, r; /* XXX we de-serialize ssh->kex->my, modify it, and change it */ if ((r = kex_buf2prop(ssh->kex->my, NULL, &proposal)) != 0) @@ -552,15 +554,20 @@ _ssh_order_hostkeyalgs(struct ssh *ssh) while ((alg = strsep(&avail, ",")) && *alg != '\0') { if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC) continue; + nid = sshkey_ecdsa_nid_from_name(alg); TAILQ_FOREACH(k, &ssh->public_keys, next) { - if (k->key->type == ktype || - (sshkey_is_cert(k->key) && k->key->type == - sshkey_type_plain(ktype))) { - if (*replace != '\0') - strlcat(replace, ",", maxlen); - strlcat(replace, alg, maxlen); - break; - } + if (k->key->type != ktype && + (!sshkey_is_cert(k->key) || + k->key->type != sshkey_type_plain(ktype))) + continue; + if (sshkey_type_plain(k->key->type) == KEY_ECDSA && + k->key->ecdsa_nid != nid) + continue; + /* Candidate */ + if (*replace != '\0') + strlcat(replace, ",", maxlen); + strlcat(replace, alg, maxlen); + break; } } if (*replace != '\0') { diff --git a/ssh_config.0 b/ssh_config.0 index ef6c0936a1c..5e692480316 100644 --- a/ssh_config.0 +++ b/ssh_config.0 @@ -55,11 +55,11 @@ DESCRIPTION Match keyword are satisfied. Match conditions are specified using one or more criteria or the single token all which always matches. The available criteria keywords are: canonical, final, - exec, localnetwork, host, originalhost, tagged, user, and - localuser. The all criteria must appear alone or immediately - after canonical or final. Other criteria may be combined - arbitrarily. All criteria but all, canonical, and final require - an argument. Criteria may be negated by prepending an + exec, localnetwork, host, originalhost, tagged, command, user, + localuser, and version. The all criteria must appear alone or + immediately after canonical or final. Other criteria may be + combined arbitrarily. All criteria but all, canonical, and final + require an argument. Criteria may be negated by prepending an exclamation mark (M-bM-^@M-^X!M-bM-^@M-^Y). The canonical keyword matches only when the configuration file is @@ -89,16 +89,32 @@ DESCRIPTION The other keywords' criteria must be single entries or comma- separated lists and may use the wildcard and negation operators - described in the PATTERNS section. The criteria for the host - keyword are matched against the target hostname, after any - substitution by the Hostname or CanonicalizeHostname options. - The originalhost keyword matches against the hostname as it was - specified on the command-line. The tagged keyword matches a tag - name specified by a prior Tag directive or on the ssh(1) command- - line using the -P flag. The user keyword matches against the - target username on the remote host. The localuser keyword - matches against the name of the local user running ssh(1) (this - keyword may be useful in system-wide ssh_config files). + described in the PATTERNS section. + + The criteria for the host keyword are matched against the target + hostname, after any substitution by the Hostname or + CanonicalizeHostname options. The originalhost keyword matches + against the hostname as it was specified on the command-line. + + The tagged keyword matches a tag name specified by a prior Tag + directive or on the ssh(1) command-line using the -P flag. The + command keyword matches the remote command that has been + requested, or the subsystem name that is being invoked (e.g. + "sftp" for an SFTP session). The empty string will match the + case where a command or tag has not been specified, i.e. M-bM-^@M-^XMatch + tag ""M-bM-^@M-^Y. The version keyword matches against the version string + of ssh(1), for example M-bM-^@M-^\OpenSSH_10.0M-bM-^@M-^]. + + The user keyword matches against the target username on the + remote host. The localuser keyword matches against the name of + the local user running ssh(1) (this keyword may be useful in + system-wide ssh_config files). + + Finally, the sessiontype keyword matches the requested session + type, which may be one of shell for interactive sessions, exec + for command execution sessions, subsystem for subsystem + invocations such as sftp(1), or none for transport-only sessions, + such as when ssh(1) is started with the -N flag. AddKeysToAgent Specifies whether keys should be automatically added to a running @@ -317,8 +333,8 @@ DESCRIPTION The default is: chacha20-poly1305@openssh.com, - aes128-ctr,aes192-ctr,aes256-ctr, - aes128-gcm@openssh.com,aes256-gcm@openssh.com + aes128-gcm@openssh.com,aes256-gcm@openssh.com, + aes128-ctr,aes192-ctr,aes256-ctr The list of available ciphers may also be obtained using "ssh -Q cipher". @@ -703,14 +719,15 @@ DESCRIPTION Include Include the specified configuration file(s). Multiple pathnames - may be specified and each pathname may contain glob(7) wildcards - and, for user configurations, shell-like M-bM-^@M-^X~M-bM-^@M-^Y references to user - home directories. Wildcards will be expanded and processed in - lexical order. Files without absolute paths are assumed to be in - ~/.ssh if included in a user configuration file or /etc/ssh if - included from the system configuration file. Include directive - may appear inside a Match or Host block to perform conditional - inclusion. + may be specified and each pathname may contain glob(7) wildcards, + tokens as described in the TOKENS section, environment variables + as described in the ENVIRONMENT VARIABLES section and, for user + configurations, shell-like M-bM-^@M-^X~M-bM-^@M-^Y references to user home + directories. Wildcards will be expanded and processed in lexical + order. Files without absolute paths are assumed to be in ~/.ssh + if included in a user configuration file or /etc/ssh if included + from the system configuration file. Include directive may appear + inside a Match or Host block to perform conditional inclusion. IPQoS Specifies the IPv4 type-of-service or DSCP class for connections. Accepted values are af11, af12, af13, af21, af22, af23, af31, @@ -740,7 +757,7 @@ DESCRIPTION KexAlgorithms Specifies the permitted KEX (Key Exchange) algorithms that will be used and their preference order. The selected algorithm will - the the first algorithm in this list that the server also + be the first algorithm in this list that the server also supports. Multiple algorithms must be comma-separated. If the specified list begins with a M-bM-^@M-^X+M-bM-^@M-^Y character, then the @@ -754,7 +771,8 @@ DESCRIPTION The default is: - sntrup761x25519-sha512@openssh.com, + mlkem768x25519-sha256, + sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, curve25519-sha256,curve25519-sha256@libssh.org, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, @@ -796,21 +814,28 @@ DESCRIPTION enabled. LocalForward - Specifies that a TCP port on the local machine be forwarded over - the secure channel to the specified host and port from the remote - machine. The first argument specifies the listener and may be - [bind_address:]port or a Unix domain socket path. The second - argument is the destination and may be host:hostport or a Unix - domain socket path if the remote host supports it. + Specifies that a TCP port or Unix-domain socket on the local + machine be forwarded over the secure channel to the specified + host and port (or Unix-domain socket) from the remote machine. + For a TCP port, the first argument must be [bind_address:]port or + a Unix domain socket path. The second argument is the + destination and may be host:hostport or a Unix domain socket path + if the remote host supports it. IPv6 addresses can be specified by enclosing addresses in square - brackets. Multiple forwardings may be specified, and additional - forwardings can be given on the command line. Only the superuser - can forward privileged ports. By default, the local port is - bound in accordance with the GatewayPorts setting. However, an - explicit bind_address may be used to bind the connection to a - specific address. The bind_address of localhost indicates that - the listening port be bound for local use only, while an empty + brackets. + + If either argument contains a '/' in it, that argument will be + interpreted as a Unix-domain socket (on the corresponding host) + rather than a TCP port. + + Multiple forwardings may be specified, and additional forwardings + can be given on the command line. Only the superuser can forward + privileged ports. By default, the local port is bound in + accordance with the GatewayPorts setting. However, an explicit + bind_address may be used to bind the connection to a specific + address. The bind_address of localhost indicates that the + listening port be bound for local use only, while an empty address or M-bM-^@M-^X*M-bM-^@M-^Y indicates that the port should be available from all interfaces. Unix domain socket paths may use the tokens described in the TOKENS section and environment variables as @@ -825,9 +850,9 @@ DESCRIPTION LogVerbose Specify one or more overrides to LogLevel. An override consists - of a pattern lists that matches the source file, function and - line number to force detailed logging for. For example, an - override pattern of: + of one or more pattern lists that matches the source file, + function and line number to force detailed logging for. For + example, an override pattern of: kex.c:*:1000,*:kex_exchange_identification():*,packet.c:* @@ -1032,27 +1057,34 @@ DESCRIPTION the TOKENS section. RemoteForward - Specifies that a TCP port on the remote machine be forwarded over - the secure channel. The remote port may either be forwarded to a - specified host and port from the local machine, or may act as a - SOCKS 4/5 proxy that allows a remote client to connect to - arbitrary destinations from the local machine. The first - argument is the listening specification and may be - [bind_address:]port or, if the remote host supports it, a Unix - domain socket path. If forwarding to a specific destination then - the second argument must be host:hostport or a Unix domain socket - path, otherwise if no destination argument is specified then the - remote forwarding will be established as a SOCKS proxy. When - acting as a SOCKS proxy, the destination of the connection can be - restricted by PermitRemoteOpen. + Specifies that a TCP port or Unix-domain socket on the remote + machine be forwarded over the secure channel. The remote port + may either be forwarded to a specified host and port or Unix- + domain socket from the local machine, or may act as a SOCKS 4/5 + proxy that allows a remote client to connect to arbitrary + destinations from the local machine. The first argument is the + listening specification and may be [bind_address:]port or, if the + remote host supports it, a Unix domain socket path. If + forwarding to a specific destination then the second argument + must be host:hostport or a Unix domain socket path, otherwise if + no destination argument is specified then the remote forwarding + will be established as a SOCKS proxy. When acting as a SOCKS + proxy, the destination of the connection can be restricted by + PermitRemoteOpen. IPv6 addresses can be specified by enclosing addresses in square - brackets. Multiple forwardings may be specified, and additional - forwardings can be given on the command line. Privileged ports - can be forwarded only when logging in as root on the remote - machine. Unix domain socket paths may use the tokens described - in the TOKENS section and environment variables as described in - the ENVIRONMENT VARIABLES section. + brackets. + + If either argument contains a '/' in it, that argument will be + interpreted as a Unix-domain socket (on the corresponding host) + rather than a TCP port. + + Multiple forwardings may be specified, and additional forwardings + can be given on the command line. Privileged ports can be + forwarded only when logging in as root on the remote machine. + Unix domain socket paths may use the tokens described in the + TOKENS section and environment variables as described in the + ENVIRONMENT VARIABLES section. If the port argument is 0, the listen port will be dynamically allocated on the server and reported to the client at run time. @@ -1152,9 +1184,13 @@ DESCRIPTION execution). SetEnv Directly specify one or more environment variables and their - contents to be sent to the server. Similarly to SendEnv, with - the exception of the TERM variable, the server must be prepared - to accept the environment variable. + contents to be sent to the server in the form M-bM-^@M-^\NAME=VALUEM-bM-^@M-^]. + Similarly to SendEnv, with the exception of the TERM variable, + the server must be prepared to accept the environment variable. + + The M-bM-^@M-^\VALUEM-bM-^@M-^] may use the tokens described in the TOKENS section + and environment variables as described in the ENVIRONMENT + VARIABLES section. StdinNull Redirects stdin from /dev/null (actually, prevents reading from @@ -1273,7 +1309,10 @@ DESCRIPTION User Specifies the user to log in as. This can be useful when a different user name is used on different machines. This saves the trouble of having to remember to give the user name on the - command line. + command line. Arguments to User may use the tokens described in + the TOKENS section (with the exception of %r and %C) and + environment variables as described in the ENVIRONMENT VARIABLES + section. UserKnownHostsFile Specifies one or more files to use for the user host key @@ -1296,6 +1335,11 @@ DESCRIPTION See also VERIFYING HOST KEYS in ssh(1). + VersionAddendum + Optionally specifies additional text to append to the SSH + protocol banner sent by the client upon connection. The default + is none. + VisualHostKey If this flag is set to yes, an ASCII art representation of the remote host key fingerprint is printed in addition to the @@ -1373,10 +1417,10 @@ TOKENS %t The type of the server host key, e.g. ssh-ed25519. %u The local username. - CertificateFile, ControlPath, IdentityAgent, IdentityFile, + CertificateFile, ControlPath, IdentityAgent, IdentityFile, Include, KnownHostsCommand, LocalForward, Match exec, RemoteCommand, - RemoteForward, RevokedHostKeys, and UserKnownHostsFile accept the tokens - %%, %C, %d, %h, %i, %j, %k, %L, %l, %n, %p, %r, and %u. + RemoteForward, RevokedHostKeys, UserKnownHostsFile and VersionAddendum + accept the tokens %%, %C, %d, %h, %i, %j, %k, %L, %l, %n, %p, %r, and %u. KnownHostsCommand additionally accepts the tokens %f, %H, %I, %K and %t. @@ -1401,9 +1445,9 @@ ENVIRONMENT VARIABLES the setting for that keyword will be ignored. The keywords CertificateFile, ControlPath, IdentityAgent, IdentityFile, - KnownHostsCommand, and UserKnownHostsFile support environment variables. - The keywords LocalForward and RemoteForward support environment variables - only for Unix domain socket paths. + Include, KnownHostsCommand, and UserKnownHostsFile support environment + variables. The keywords LocalForward and RemoteForward support + environment variables only for Unix domain socket paths. FILES ~/.ssh/config @@ -1428,4 +1472,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 7.5 June 17, 2024 OpenBSD 7.5 +OpenBSD 7.6 March 3, 2025 OpenBSD 7.6 diff --git a/ssh_config.5 b/ssh_config.5 index 2e1902283d7..894d738310c 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.396 2024/06/17 08:30:29 djm Exp $ -.Dd $Mdocdate: June 17 2024 $ +.\" $OpenBSD: ssh_config.5,v 1.413 2025/03/03 06:53:09 dtucker Exp $ +.Dd $Mdocdate: March 3 2025 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -145,9 +145,11 @@ The available criteria keywords are: .Cm host , .Cm originalhost , .Cm tagged , +.Cm command , .Cm user , +.Cm localuser , and -.Cm localuser . +.Cm version . The .Cm all criteria must appear alone or immediately after @@ -212,6 +214,7 @@ The other keywords' criteria must be single entries or comma-separated lists and may use the wildcard and negation operators described in the .Sx PATTERNS section. +.Pp The criteria for the .Cm host keyword are matched against the target hostname, after any substitution @@ -223,6 +226,7 @@ options. The .Cm originalhost keyword matches against the hostname as it was specified on the command-line. +.Pp The .Cm tagged keyword matches a tag name specified by a prior @@ -233,6 +237,22 @@ command-line using the .Fl P flag. The +.Cm command +keyword matches the remote command that has been requested, or the subsystem +name that is being invoked (e.g.\& +.Qq sftp +for an SFTP session). +The empty string will match the case where a command or tag has not been +specified, i.e.\& +.Sq Match tag \&"\&" . +The +.Cm version +keyword matches against the version string of +.Xr ssh 1 , +for example +.Dq OpenSSH_10.0 . +.Pp +The .Cm user keyword matches against the target username on the remote host. The @@ -242,6 +262,24 @@ keyword matches against the name of the local user running (this keyword may be useful in system-wide .Nm files). +.Pp +Finally, the +.Cm sessiontype +keyword matches the requested session type, which may be one of +.Cm shell +for interactive sessions, +.Cm exec +for command execution sessions, +.Cm subsystem +for subsystem invocations such as +.Xr sftp 1 , +or +.Cm none +for transport-only sessions, such as when +.Xr ssh 1 +is started with the +.Fl N +flag. .It Cm AddKeysToAgent Specifies whether keys should be automatically added to a running .Xr ssh-agent 1 . @@ -581,8 +619,8 @@ chacha20-poly1305@openssh.com The default is: .Bd -literal -offset indent chacha20-poly1305@openssh.com, -aes128-ctr,aes192-ctr,aes256-ctr, -aes128-gcm@openssh.com,aes256-gcm@openssh.com +aes128-gcm@openssh.com,aes256-gcm@openssh.com, +aes128-ctr,aes192-ctr,aes256-ctr .Ed .Pp The list of available ciphers may also be obtained using @@ -1182,7 +1220,12 @@ to unknown options that appear before it. Include the specified configuration file(s). Multiple pathnames may be specified and each pathname may contain .Xr glob 7 -wildcards and, for user configurations, shell-like +wildcards, +tokens as described in the +.Sx TOKENS +section, environment variables as described in the +.Sx ENVIRONMENT VARIABLES +section and, for user configurations, shell-like .Sq ~ references to user home directories. Wildcards will be expanded and processed in lexical order. @@ -1262,7 +1305,7 @@ and .It Cm KexAlgorithms Specifies the permitted KEX (Key Exchange) algorithms that will be used and their preference order. -The selected algorithm will the the first algorithm in this list that +The selected algorithm will be the first algorithm in this list that the server also supports. Multiple algorithms must be comma-separated. .Pp @@ -1281,7 +1324,8 @@ default set. .Pp The default is: .Bd -literal -offset indent -sntrup761x25519-sha512@openssh.com, +mlkem768x25519-sha256, +sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, curve25519-sha256,curve25519-sha256@libssh.org, ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, diffie-hellman-group-exchange-sha256, @@ -1338,9 +1382,11 @@ This directive is ignored unless .Cm PermitLocalCommand has been enabled. .It Cm LocalForward -Specifies that a TCP port on the local machine be forwarded over -the secure channel to the specified host and port from the remote machine. -The first argument specifies the listener and may be +Specifies that a TCP port or Unix-domain socket on the local machine +be forwarded over +the secure channel to the specified host and port (or Unix-domain socket) +from the remote machine. +For a TCP port, the first argument must be .Sm off .Oo Ar bind_address : Oc Ar port .Sm on @@ -1350,6 +1396,11 @@ The second argument is the destination and may be or a Unix domain socket path if the remote host supports it. .Pp IPv6 addresses can be specified by enclosing addresses in square brackets. +.Pp +If either argument contains a '/' in it, that argument will be +interpreted as a Unix-domain socket (on the corresponding host) rather +than a TCP port. +.Pp Multiple forwardings may be specified, and additional forwardings can be given on the command line. Only the superuser can forward privileged ports. @@ -1382,8 +1433,8 @@ DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of verbose output. .It Cm LogVerbose Specify one or more overrides to LogLevel. -An override consists of a pattern lists that matches the source file, function -and line number to force detailed logging for. +An override consists of one or more pattern lists that matches the +source file, function and line number to force detailed logging for. For example, an override pattern of: .Bd -literal -offset indent kex.c:*:1000,*:kex_exchange_identification():*,packet.c:* @@ -1578,14 +1629,12 @@ ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p .Ed .It Cm ProxyJump Specifies one or more jump proxies as either -.Xo .Sm off .Op Ar user No @ .Ar host .Op : Ns Ar port .Sm on -or an ssh URI -.Xc . +or an ssh URI. Multiple proxies may be separated by comma characters and will be visited sequentially. Setting this option will cause @@ -1701,9 +1750,10 @@ accept the tokens described in the .Sx TOKENS section. .It Cm RemoteForward -Specifies that a TCP port on the remote machine be forwarded over -the secure channel. +Specifies that a TCP port or Unix-domain socket on the remote machine +be forwarded over the secure channel. The remote port may either be forwarded to a specified host and port +or Unix-domain socket from the local machine, or may act as a SOCKS 4/5 proxy that allows a remote client to connect to arbitrary destinations from the local machine. The first argument is the listening specification and may be @@ -1721,6 +1771,11 @@ restricted by .Cm PermitRemoteOpen . .Pp IPv6 addresses can be specified by enclosing addresses in square brackets. +.Pp +If either argument contains a '/' in it, that argument will be +interpreted as a Unix-domain socket (on the corresponding host) rather +than a TCP port. +.Pp Multiple forwardings may be specified, and additional forwardings can be given on the command line. Privileged ports can be forwarded only when @@ -1888,12 +1943,21 @@ option) or (shell or command execution). .It Cm SetEnv Directly specify one or more environment variables and their contents to -be sent to the server. +be sent to the server in the form +.Dq NAME=VALUE . Similarly to .Cm SendEnv , with the exception of the .Ev TERM variable, the server must be prepared to accept the environment variable. +.Pp +The +.Dq VALUE +may use the tokens described in the +.Sx TOKENS +section and environment variables as described in the +.Sx ENVIRONMENT VARIABLES +section. .It Cm StdinNull Redirects stdin from .Pa /dev/null @@ -2093,6 +2157,15 @@ Specifies the user to log in as. This can be useful when a different user name is used on different machines. This saves the trouble of having to remember to give the user name on the command line. +Arguments to +.Cm User +may use the tokens described in the +.Sx TOKENS +section +(with the exception of %r and %C) +and environment variables as described in the +.Sx ENVIRONMENT VARIABLES +section. .It Cm UserKnownHostsFile Specifies one or more files to use for the user host key database, separated by whitespace. @@ -2132,6 +2205,11 @@ See also .Sx VERIFYING HOST KEYS in .Xr ssh 1 . +.It Cm VersionAddendum +Optionally specifies additional text to append to the SSH protocol banner +sent by the client upon connection. +The default is +.Cm none . .It Cm VisualHostKey If this flag is set to .Cm yes , @@ -2270,14 +2348,16 @@ The local username. .Cm ControlPath , .Cm IdentityAgent , .Cm IdentityFile , +.Cm Include , .Cm KnownHostsCommand , .Cm LocalForward , .Cm Match exec , .Cm RemoteCommand , .Cm RemoteForward , .Cm RevokedHostKeys , -and .Cm UserKnownHostsFile +and +.Cm VersionAddendum accept the tokens %%, %C, %d, %h, %i, %j, %k, %L, %l, %n, %p, %r, and %u. .Pp .Cm KnownHostsCommand @@ -2318,6 +2398,7 @@ The keywords .Cm ControlPath , .Cm IdentityAgent , .Cm IdentityFile , +.Cm Include , .Cm KnownHostsCommand , and .Cm UserKnownHostsFile diff --git a/sshbuf-getput-crypto.c b/sshbuf-getput-crypto.c index af3f39795d6..e7bffe225cd 100644 --- a/sshbuf-getput-crypto.c +++ b/sshbuf-getput-crypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf-getput-crypto.c,v 1.11 2024/02/01 02:37:33 djm Exp $ */ +/* $OpenBSD: sshbuf-getput-crypto.c,v 1.12 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -176,5 +176,15 @@ sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v) return sshbuf_put_ec(buf, EC_KEY_get0_public_key(v), EC_KEY_get0_group(v)); } + +int +sshbuf_put_ec_pkey(struct sshbuf *buf, EVP_PKEY *pkey) +{ + const EC_KEY *ec; + + if ((ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) + return SSH_ERR_LIBCRYPTO_ERROR; + return sshbuf_put_eckey(buf, ec); +} #endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ diff --git a/sshbuf.c b/sshbuf.c index d7f4e4ab650..1b714e5f9c7 100644 --- a/sshbuf.c +++ b/sshbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf.c,v 1.19 2022/12/02 04:40:27 djm Exp $ */ +/* $OpenBSD: sshbuf.c,v 1.23 2024/08/14 15:42:18 tobias Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -57,6 +57,7 @@ sshbuf_check_sanity(const struct sshbuf *buf) SSHBUF_TELL("sanity"); if (__predict_false(buf == NULL || (!buf->readonly && buf->d != buf->cd) || + buf->parent == buf || buf->refcount < 1 || buf->refcount > SSHBUF_REFS_MAX || buf->cd == NULL || buf->max_size > SSHBUF_SIZE_MAX || @@ -93,7 +94,7 @@ sshbuf_new(void) { struct sshbuf *ret; - if ((ret = calloc(sizeof(*ret), 1)) == NULL) + if ((ret = calloc(1, sizeof(*ret))) == NULL) return NULL; ret->alloc = SSHBUF_SIZE_INIT; ret->max_size = SSHBUF_SIZE_MAX; @@ -113,7 +114,7 @@ sshbuf_from(const void *blob, size_t len) struct sshbuf *ret; if (blob == NULL || len > SSHBUF_SIZE_MAX || - (ret = calloc(sizeof(*ret), 1)) == NULL) + (ret = calloc(1, sizeof(*ret))) == NULL) return NULL; ret->alloc = ret->size = ret->max_size = len; ret->readonly = 1; @@ -132,7 +133,8 @@ sshbuf_set_parent(struct sshbuf *child, struct sshbuf *parent) if ((r = sshbuf_check_sanity(child)) != 0 || (r = sshbuf_check_sanity(parent)) != 0) return r; - if (child->parent != NULL && child->parent != parent) + if ((child->parent != NULL && child->parent != parent) || + child == parent) return SSH_ERR_INTERNAL_ERROR; child->parent = parent; child->parent->refcount++; @@ -179,16 +181,14 @@ sshbuf_free(struct sshbuf *buf) return; /* - * If we are a child, the free our parent to decrement its reference + * If we are a child, then free our parent to decrement its reference * count and possibly free it. */ sshbuf_free(buf->parent); buf->parent = NULL; - if (!buf->readonly) { - explicit_bzero(buf->d, buf->alloc); - free(buf->d); - } + if (!buf->readonly) + freezero(buf->d, buf->alloc); freezero(buf, sizeof(*buf)); } diff --git a/sshbuf.h b/sshbuf.h index 1f17fcc4b42..6ba2c9ba223 100644 --- a/sshbuf.h +++ b/sshbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshbuf.h,v 1.28 2022/12/02 04:40:27 djm Exp $ */ +/* $OpenBSD: sshbuf.h,v 1.29 2024/08/15 00:51:51 djm Exp $ */ /* * Copyright (c) 2011 Damien Miller * @@ -23,6 +23,7 @@ #include #ifdef WITH_OPENSSL # include +# include # ifdef OPENSSL_HAS_ECC # include # endif /* OPENSSL_HAS_ECC */ @@ -223,6 +224,7 @@ int sshbuf_get_ec(struct sshbuf *buf, EC_POINT *v, const EC_GROUP *g); int sshbuf_get_eckey(struct sshbuf *buf, EC_KEY *v); int sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g); int sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v); +int sshbuf_put_ec_pkey(struct sshbuf *buf, EVP_PKEY *pkey); # endif /* OPENSSL_HAS_ECC */ #endif /* WITH_OPENSSL */ diff --git a/sshconnect.c b/sshconnect.c index 022c6361042..dc28a5e4a9a 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.368 2024/04/30 02:10:49 djm Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.369 2024/12/06 16:21:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1641,7 +1641,8 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost, lowercase(host); /* Exchange protocol version identification strings with the server. */ - if ((r = kex_exchange_identification(ssh, timeout_ms, NULL)) != 0) + if ((r = kex_exchange_identification(ssh, timeout_ms, + options.version_addendum)) != 0) sshpkt_fatal(ssh, r, "banner exchange"); /* Put the connection into non-blocking mode. */ diff --git a/sshconnect.h b/sshconnect.h index 8b0466f299e..30827016040 100644 --- a/sshconnect.h +++ b/sshconnect.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.h,v 1.48 2024/04/30 02:10:49 djm Exp $ */ +/* $OpenBSD: sshconnect.h,v 1.49 2025/03/01 06:11:26 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -52,9 +52,8 @@ struct ssh; struct hostkeys; struct ssh_conn_info; -/* default argument for client percent expansions */ -#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(conn_info) \ - "C", conn_info->conn_hash_hex, \ +/* default argument for client percent expansions, minus remote user */ +#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS_NOUSER(conn_info) \ "L", conn_info->shorthost, \ "i", conn_info->uidstr, \ "k", conn_info->keyalias, \ @@ -63,10 +62,15 @@ struct ssh_conn_info; "p", conn_info->portstr, \ "d", conn_info->homedir, \ "h", conn_info->remhost, \ - "r", conn_info->remuser, \ "u", conn_info->locuser, \ "j", conn_info->jmphost +/* same plus remote user and hash which has user as a component */ +#define DEFAULT_CLIENT_PERCENT_EXPAND_ARGS(conn_info) \ + DEFAULT_CLIENT_PERCENT_EXPAND_ARGS_NOUSER(conn_info), \ + "C", conn_info->conn_hash_hex, \ + "r", conn_info->remuser + int ssh_connect(struct ssh *, const char *, const char *, struct addrinfo *, struct sockaddr_storage *, u_short, int, int *, int); diff --git a/sshconnect2.c b/sshconnect2.c index 1fe517a4f4b..d7d8ef8e01b 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -278,6 +278,7 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, #endif ssh->kex->kex[KEX_C25519_SHA256] = kex_gen_client; ssh->kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_client; + ssh->kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_client; ssh->kex->verify_host_key=&verify_host_key_callback; ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done); @@ -1929,10 +1930,8 @@ userauth_pubkey(struct ssh *ssh) debug("Trying private key: %s", id->filename); id->key = load_identity_file(id); if (id->key != NULL) { - if (id->key != NULL) { - id->isprivate = 1; - sent = sign_and_send_pubkey(ssh, id); - } + id->isprivate = 1; + sent = sign_and_send_pubkey(ssh, id); sshkey_free(id->key); id->key = NULL; id->isprivate = 0; diff --git a/sshd-auth.c b/sshd-auth.c new file mode 100644 index 00000000000..ad22dc338ee --- /dev/null +++ b/sshd-auth.c @@ -0,0 +1,896 @@ +/* $OpenBSD: sshd-auth.c,v 1.3 2025/01/16 06:37:10 dtucker Exp $ */ +/* + * SSH2 implementation: + * Privilege Separation: + * + * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. + * Copyright (c) 2002 Niels Provos. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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. + */ + +#include "includes.h" + +#include +#include +#include +#include +#include +#include + +#include "openbsd-compat/sys-tree.h" +#include "openbsd-compat/sys-queue.h" + +#include +#include +#include +#ifdef HAVE_PATHS_H +# include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WITH_OPENSSL +#include +#include +#endif + +#include "xmalloc.h" +#include "ssh.h" +#include "ssh2.h" +#include "sshpty.h" +#include "packet.h" +#include "log.h" +#include "sshbuf.h" +#include "misc.h" +#include "match.h" +#include "servconf.h" +#include "uidswap.h" +#include "compat.h" +#include "cipher.h" +#include "digest.h" +#include "sshkey.h" +#include "kex.h" +#include "authfile.h" +#include "pathnames.h" +#include "atomicio.h" +#include "canohost.h" +#include "hostfile.h" +#include "auth.h" +#include "authfd.h" +#include "msg.h" +#include "dispatch.h" +#include "channels.h" +#include "session.h" +#include "monitor.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" +#include "auth-options.h" +#include "version.h" +#include "ssherr.h" +#include "sk-api.h" +#include "srclimit.h" +#include "ssh-sandbox.h" +#include "dh.h" + +/* Privsep fds */ +#define PRIVSEP_MONITOR_FD (STDERR_FILENO + 1) +#define PRIVSEP_LOG_FD (STDERR_FILENO + 2) +#define PRIVSEP_MIN_FREE_FD (STDERR_FILENO + 3) + +extern char *__progname; + +/* Server configuration options. */ +ServerOptions options; + +/* Name of the server configuration file. */ +char *config_file_name = _PATH_SERVER_CONFIG_FILE; + +/* + * Debug mode flag. This can be set on the command line. If debug + * mode is enabled, extra debugging output will be sent to the system + * log, the daemon will not go to background, and will exit after processing + * the first connection. + */ +int debug_flag = 0; + +/* Flag indicating that the daemon is being started from inetd. */ +static int inetd_flag = 0; + +/* Saved arguments to main(). */ +static char **saved_argv; +static int saved_argc; + + +/* Daemon's agent connection */ +int auth_sock = -1; +static int have_agent = 0; + +u_int num_hostkeys; +struct sshkey **host_pubkeys; /* all public host keys */ +struct sshkey **host_certificates; /* all public host certificates */ + +/* record remote hostname or ip */ +u_int utmp_len = HOST_NAME_MAX+1; + +/* variables used for privilege separation */ +struct monitor *pmonitor = NULL; +int privsep_is_preauth = 1; +static int privsep_chroot = 1; + +/* global connection state and authentication contexts */ +Authctxt *the_authctxt = NULL; +struct ssh *the_active_state; + +/* global key/cert auth options. XXX move to permanent ssh->authctxt? */ +struct sshauthopt *auth_opts = NULL; + +/* sshd_config buffer */ +struct sshbuf *cfg; + +/* Included files from the configuration file */ +struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); + +/* message to be displayed after login */ +struct sshbuf *loginmsg; + +/* Prototypes for various functions defined later in this file. */ +static void do_ssh2_kex(struct ssh *); + +/* Unprivileged user */ +struct passwd *privsep_pw = NULL; + +#ifndef HAVE_PLEDGE +static struct ssh_sandbox *box; +#endif + +/* XXX stub */ +int +mm_is_monitor(void) +{ + return 0; +} + +static void +privsep_child_demote(void) +{ + gid_t gidset[1]; + +#ifndef HAVE_PLEDGE + if ((box = ssh_sandbox_init(pmonitor)) == NULL) + fatal_f("ssh_sandbox_init failed"); +#endif + /* Demote the child */ + if (privsep_chroot) { + /* Change our root directory */ + if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) + fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, + strerror(errno)); + if (chdir("/") == -1) + fatal("chdir(\"/\"): %s", strerror(errno)); + + /* + * Drop our privileges + * NB. Can't use setusercontext() after chroot. + */ + debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid, + (u_int)privsep_pw->pw_gid); + gidset[0] = privsep_pw->pw_gid; + if (setgroups(1, gidset) == -1) + fatal("setgroups: %.100s", strerror(errno)); + permanently_set_uid(privsep_pw); + } + + /* sandbox ourselves */ +#ifdef HAVE_PLEDGE + if (pledge("stdio", NULL) == -1) + fatal_f("pledge()"); +#else + ssh_sandbox_child(box); +#endif +} + +static void +append_hostkey_type(struct sshbuf *b, const char *s) +{ + int r; + + if (match_pattern_list(s, options.hostkeyalgorithms, 0) != 1) { + debug3_f("%s key not permitted by HostkeyAlgorithms", s); + return; + } + if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) > 0 ? "," : "", s)) != 0) + fatal_fr(r, "sshbuf_putf"); +} + +static char * +list_hostkey_types(void) +{ + struct sshbuf *b; + struct sshkey *key; + char *ret; + u_int i; + + if ((b = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + for (i = 0; i < options.num_host_key_files; i++) { + key = host_pubkeys[i]; + if (key == NULL) + continue; + switch (key->type) { + case KEY_RSA: + /* for RSA we also support SHA2 signatures */ + append_hostkey_type(b, "rsa-sha2-512"); + append_hostkey_type(b, "rsa-sha2-256"); + /* FALLTHROUGH */ + case KEY_DSA: + case KEY_ECDSA: + case KEY_ED25519: + case KEY_ECDSA_SK: + case KEY_ED25519_SK: + case KEY_XMSS: + append_hostkey_type(b, sshkey_ssh_name(key)); + break; + } + /* If the private key has a cert peer, then list that too */ + key = host_certificates[i]; + if (key == NULL) + continue; + switch (key->type) { + case KEY_RSA_CERT: + /* for RSA we also support SHA2 signatures */ + append_hostkey_type(b, + "rsa-sha2-512-cert-v01@openssh.com"); + append_hostkey_type(b, + "rsa-sha2-256-cert-v01@openssh.com"); + /* FALLTHROUGH */ + case KEY_DSA_CERT: + case KEY_ECDSA_CERT: + case KEY_ED25519_CERT: + case KEY_ECDSA_SK_CERT: + case KEY_ED25519_SK_CERT: + case KEY_XMSS_CERT: + append_hostkey_type(b, sshkey_ssh_name(key)); + break; + } + } + if ((ret = sshbuf_dup_string(b)) == NULL) + fatal_f("sshbuf_dup_string failed"); + sshbuf_free(b); + debug_f("%s", ret); + return ret; +} + +struct sshkey * +get_hostkey_public_by_type(int type, int nid, struct ssh *ssh) +{ + u_int i; + struct sshkey *key; + + for (i = 0; i < options.num_host_key_files; i++) { + switch (type) { + case KEY_RSA_CERT: + case KEY_DSA_CERT: + case KEY_ECDSA_CERT: + case KEY_ED25519_CERT: + case KEY_ECDSA_SK_CERT: + case KEY_ED25519_SK_CERT: + case KEY_XMSS_CERT: + key = host_certificates[i]; + break; + default: + key = host_pubkeys[i]; + break; + } + if (key == NULL || key->type != type) + continue; + switch (type) { + case KEY_ECDSA: + case KEY_ECDSA_SK: + case KEY_ECDSA_CERT: + case KEY_ECDSA_SK_CERT: + if (key->ecdsa_nid != nid) + continue; + /* FALLTHROUGH */ + default: + return key; + } + } + return NULL; +} + +/* XXX remove */ +struct sshkey * +get_hostkey_private_by_type(int type, int nid, struct ssh *ssh) +{ + return NULL; +} + +/* XXX remove */ +struct sshkey * +get_hostkey_by_index(int ind) +{ + return NULL; +} + +struct sshkey * +get_hostkey_public_by_index(int ind, struct ssh *ssh) +{ + if (ind < 0 || (u_int)ind >= options.num_host_key_files) + return (NULL); + return host_pubkeys[ind]; +} + +int +get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh) +{ + u_int i; + + for (i = 0; i < options.num_host_key_files; i++) { + if (sshkey_is_cert(key)) { + if (key == host_certificates[i] || + (compare && host_certificates[i] && + sshkey_equal(key, host_certificates[i]))) + return (i); + } else { + if (key == host_pubkeys[i] || + (compare && host_pubkeys[i] && + sshkey_equal(key, host_pubkeys[i]))) + return (i); + } + } + return (-1); +} + +static void +usage(void) +{ + fprintf(stderr, "%s, %s\n", SSH_VERSION, SSH_OPENSSL_VERSION); + fprintf(stderr, +"usage: sshd [-46DdeGiqTtV] [-C connection_spec] [-c host_cert_file]\n" +" [-E log_file] [-f config_file] [-g login_grace_time]\n" +" [-h host_key_file] [-o option] [-p port] [-u len]\n" + ); + exit(1); +} + +static void +parse_hostkeys(struct sshbuf *hostkeys) +{ + int r; + u_int num_keys = 0; + struct sshkey *k; + const u_char *cp; + size_t len; + + while (sshbuf_len(hostkeys) != 0) { + if (num_keys > 2048) + fatal_f("too many hostkeys"); + host_pubkeys = xrecallocarray(host_pubkeys, + num_keys, num_keys + 1, sizeof(*host_pubkeys)); + host_certificates = xrecallocarray(host_certificates, + num_keys, num_keys + 1, sizeof(*host_certificates)); + /* public key */ + k = NULL; + if ((r = sshbuf_get_string_direct(hostkeys, &cp, &len)) != 0) + fatal_fr(r, "extract pubkey"); + if (len != 0 && (r = sshkey_from_blob(cp, len, &k)) != 0) + fatal_fr(r, "parse pubkey"); + host_pubkeys[num_keys] = k; + if (k) + debug2_f("key %u: %s", num_keys, sshkey_ssh_name(k)); + /* certificate */ + k = NULL; + if ((r = sshbuf_get_string_direct(hostkeys, &cp, &len)) != 0) + fatal_fr(r, "extract pubkey"); + if (len != 0 && (r = sshkey_from_blob(cp, len, &k)) != 0) + fatal_fr(r, "parse pubkey"); + host_certificates[num_keys] = k; + if (k) + debug2_f("cert %u: %s", num_keys, sshkey_ssh_name(k)); + num_keys++; + } + num_hostkeys = num_keys; +} + +static void +recv_privsep_state(struct ssh *ssh, struct sshbuf *conf, + uint64_t *timing_secretp) +{ + struct sshbuf *hostkeys; + + debug3_f("begin"); + + mm_get_state(ssh, &includes, conf, NULL, timing_secretp, + &hostkeys, NULL, NULL, NULL, NULL); + parse_hostkeys(hostkeys); + + sshbuf_free(hostkeys); + + debug3_f("done"); +} + +/* + * Main program for the daemon. + */ +int +main(int ac, char **av) +{ + struct ssh *ssh = NULL; + extern char *optarg; + extern int optind; + int r, opt, have_key = 0; + int sock_in = -1, sock_out = -1, rexeced_flag = 0; + char *line, *logfile = NULL; + u_int i; + mode_t new_umask; + Authctxt *authctxt; + struct connection_info *connection_info = NULL; + sigset_t sigmask; + uint64_t timing_secret = 0; + + closefrom(PRIVSEP_MIN_FREE_FD); + sigemptyset(&sigmask); + sigprocmask(SIG_SETMASK, &sigmask, NULL); + +#ifdef HAVE_SECUREWARE + (void)set_auth_parameters(ac, av); +#endif + __progname = ssh_get_progname(av[0]); + + /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ + saved_argc = ac; + saved_argv = xcalloc(ac + 1, sizeof(*saved_argv)); + for (i = 0; (int)i < ac; i++) + saved_argv[i] = xstrdup(av[i]); + saved_argv[i] = NULL; + + seed_rng(); + +#ifndef HAVE_SETPROCTITLE + /* Prepare for later setproctitle emulation */ + compat_init_setproctitle(ac, av); + av = saved_argv; +#endif + + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ + sanitise_stdfd(); + + /* Initialize configuration options to their default values. */ + initialize_server_options(&options); + + /* Parse command-line arguments. */ + while ((opt = getopt(ac, av, + "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) { + switch (opt) { + case '4': + options.address_family = AF_INET; + break; + case '6': + options.address_family = AF_INET6; + break; + case 'f': + config_file_name = optarg; + break; + case 'c': + servconf_add_hostcert("[command-line]", 0, + &options, optarg); + break; + case 'd': + if (debug_flag == 0) { + debug_flag = 1; + options.log_level = SYSLOG_LEVEL_DEBUG1; + } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) + options.log_level++; + break; + case 'D': + /* ignore */ + break; + case 'E': + logfile = optarg; + /* FALLTHROUGH */ + case 'e': + /* ignore */ + break; + case 'i': + inetd_flag = 1; + break; + case 'r': + /* ignore */ + break; + case 'R': + rexeced_flag = 1; + break; + case 'Q': + /* ignored */ + break; + case 'q': + options.log_level = SYSLOG_LEVEL_QUIET; + break; + case 'b': + /* protocol 1, ignored */ + break; + case 'p': + options.ports_from_cmdline = 1; + if (options.num_ports >= MAX_PORTS) { + fprintf(stderr, "too many ports.\n"); + exit(1); + } + options.ports[options.num_ports++] = a2port(optarg); + if (options.ports[options.num_ports-1] <= 0) { + fprintf(stderr, "Bad port number.\n"); + exit(1); + } + break; + case 'g': + if ((options.login_grace_time = convtime(optarg)) == -1) { + fprintf(stderr, "Invalid login grace time.\n"); + exit(1); + } + break; + case 'k': + /* protocol 1, ignored */ + break; + case 'h': + servconf_add_hostkey("[command-line]", 0, + &options, optarg, 1); + break; + case 't': + case 'T': + case 'G': + fatal("test/dump modes not supported"); + break; + case 'C': + connection_info = server_get_connection_info(ssh, 0, 0); + if (parse_server_match_testspec(connection_info, + optarg) == -1) + exit(1); + break; + case 'u': + utmp_len = (u_int)strtonum(optarg, 0, HOST_NAME_MAX+1+1, NULL); + if (utmp_len > HOST_NAME_MAX+1) { + fprintf(stderr, "Invalid utmp length.\n"); + exit(1); + } + break; + case 'o': + line = xstrdup(optarg); + if (process_server_config_line(&options, line, + "command-line", 0, NULL, NULL, &includes) != 0) + exit(1); + free(line); + break; + case 'V': + fprintf(stderr, "%s, %s\n", + SSH_VERSION, SSH_OPENSSL_VERSION); + exit(0); + default: + usage(); + break; + } + } + + if (!rexeced_flag) + fatal("sshd-auth should not be executed directly"); + +#ifdef WITH_OPENSSL + OpenSSL_add_all_algorithms(); +#endif + +// Windows logging handled by sending debug messages to the parent sshd process +// because an unprivileged sshd-auth process cannot open a log file owned by system +#ifndef WINDOWS + /* If requested, redirect the logs to the specified logfile. */ + if (logfile != NULL) { + char *cp, pid_s[32]; + + snprintf(pid_s, sizeof(pid_s), "%ld", (unsigned long)getpid()); + cp = percent_expand(logfile, + "p", pid_s, + "P", "sshd-auth", + (char *)NULL); + log_redirect_stderr_to(cp); + free(cp); + } +#endif /* !WINDOWS */ + + log_init(__progname, + options.log_level == SYSLOG_LEVEL_NOT_SET ? + SYSLOG_LEVEL_INFO : options.log_level, + options.log_facility == SYSLOG_FACILITY_NOT_SET ? + SYSLOG_FACILITY_AUTH : options.log_facility, 1); + + /* XXX can't use monitor_init(); it makes fds */ + pmonitor = xcalloc(1, sizeof(*pmonitor)); + pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1; + pmonitor->m_recvfd = PRIVSEP_MONITOR_FD; + pmonitor->m_log_sendfd = PRIVSEP_LOG_FD; + set_log_handler(mm_log_handler, pmonitor); +#ifdef WINDOWS + fcntl(pmonitor->m_recvfd, F_SETFD, FD_CLOEXEC); + fcntl(pmonitor->m_log_sendfd, F_SETFD, FD_CLOEXEC); +#endif /* WINDOWS */ + + /* Check that there are no remaining arguments. */ + if (optind < ac) { + fprintf(stderr, "Extra argument %s.\n", av[optind]); + exit(1); + } + + /* Connection passed by stdin/out */ + if (inetd_flag) { + /* + * NB. must be different fd numbers for the !socket case, + * as packet_connection_is_on_socket() depends on this. + */ + sock_in = dup(STDIN_FILENO); + sock_out = dup(STDOUT_FILENO); + } else { + /* rexec case; accept()ed socket in ancestor listener */ + sock_in = sock_out = dup(STDIN_FILENO); + } + + if (stdfd_devnull(1, 1, 0) == -1) + error("stdfd_devnull failed"); + debug("network sockets: %d, %d", sock_in, sock_out); + + /* + * Register our connection. This turns encryption off because we do + * not have a key. + */ + if ((ssh = ssh_packet_set_connection(NULL, sock_in, sock_out)) == NULL) + fatal("Unable to create connection"); + the_active_state = ssh; + ssh_packet_set_server(ssh); + pmonitor->m_pkex = &ssh->kex; + + /* Fetch our configuration */ + if ((cfg = sshbuf_new()) == NULL) + fatal("sshbuf_new config buf failed"); + setproctitle("%s", "[session-auth early]"); + recv_privsep_state(ssh, cfg, &timing_secret); + parse_server_config(&options, "rexec", cfg, &includes, NULL, 1); + /* Fill in default values for those options not explicitly set. */ + fill_default_server_options(&options); + options.timing_secret = timing_secret; /* XXX eliminate from unpriv */ + + /* Reinit logging in case config set Level, Facility or Verbose. */ + log_init(__progname, options.log_level, options.log_facility, 1); + + debug("sshd-auth version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); + + /* Store privilege separation user for later use if required. */ + privsep_chroot = (getuid() == 0 || geteuid() == 0); + if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { + if (privsep_chroot || options.kerberos_authentication) + fatal("Privilege separation user %s does not exist", + SSH_PRIVSEP_USER); + } else { + privsep_pw = pwcopy(privsep_pw); + freezero(privsep_pw->pw_passwd, strlen(privsep_pw->pw_passwd)); + privsep_pw->pw_passwd = xstrdup("*"); + } + endpwent(); + +#ifdef WITH_OPENSSL + if (options.moduli_file != NULL) + dh_set_moduli_file(options.moduli_file); +#endif + + if (options.host_key_agent) { + if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) + setenv(SSH_AUTHSOCKET_ENV_NAME, + options.host_key_agent, 1); + if ((r = ssh_get_authentication_socket(NULL)) == 0) + have_agent = 1; + else + error_r(r, "Could not connect to agent \"%s\"", + options.host_key_agent); + } + + if (options.num_host_key_files != num_hostkeys) { + fatal("internal error: hostkeys confused (config %u recvd %u)", + options.num_host_key_files, num_hostkeys); + } + + for (i = 0; i < options.num_host_key_files; i++) { + if (host_pubkeys[i] != NULL) { + have_key = 1; + break; + } + } + if (!have_key) + fatal("internal error: received no hostkeys"); + + /* Ensure that umask disallows at least group and world write */ + new_umask = umask(0077) | 0022; + (void) umask(new_umask); + + /* Initialize the log (it is reinitialized below in case we forked). */ + log_init(__progname, options.log_level, options.log_facility, 1); + set_log_handler(mm_log_handler, pmonitor); + for (i = 0; i < options.num_log_verbose; i++) + log_verbose_add(options.log_verbose[i]); + + /* + * Chdir to the root directory so that the current disk can be + * unmounted if desired. + */ + if (chdir("/") == -1) + error("chdir(\"/\"): %s", strerror(errno)); + + /* This is the child authenticating a new connection. */ + setproctitle("%s", "[session-auth]"); + + /* Executed child processes don't need these. */ + fcntl(sock_out, F_SETFD, FD_CLOEXEC); + fcntl(sock_in, F_SETFD, FD_CLOEXEC); + + ssh_signal(SIGPIPE, SIG_IGN); + ssh_signal(SIGALRM, SIG_DFL); + ssh_signal(SIGHUP, SIG_DFL); + ssh_signal(SIGTERM, SIG_DFL); + ssh_signal(SIGQUIT, SIG_DFL); + ssh_signal(SIGCHLD, SIG_DFL); + + /* Prepare the channels layer */ + channel_init_channels(ssh); + channel_set_af(ssh, options.address_family); + server_process_channel_timeouts(ssh); + server_process_permitopen(ssh); + + ssh_packet_set_nonblocking(ssh); + + /* allocate authentication context */ + authctxt = xcalloc(1, sizeof(*authctxt)); + ssh->authctxt = authctxt; + + /* XXX global for cleanup, access from other modules */ + the_authctxt = authctxt; + + /* Set default key authentication options */ + if ((auth_opts = sshauthopt_new_with_keys_defaults()) == NULL) + fatal("allocation failed"); + + /* prepare buffer to collect messages to display to user after login */ + if ((loginmsg = sshbuf_new()) == NULL) + fatal("sshbuf_new loginmsg failed"); + auth_debug_reset(); + + /* Enable challenge-response authentication for privilege separation */ + privsep_challenge_enable(); + +#ifdef GSSAPI + /* Cache supported mechanism OIDs for later use */ + ssh_gssapi_prepare_supported_oids(); +#endif + + privsep_child_demote(); + + /* perform the key exchange */ + /* authenticate user and start session */ + do_ssh2_kex(ssh); + do_authentication2(ssh); + + /* + * The unprivileged child now transfers the current keystate and exits. + */ + mm_send_keystate(ssh, pmonitor); + ssh_packet_clear_keys(ssh); + exit(0); +} + +int +sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, + struct sshkey *pubkey, u_char **signature, size_t *slenp, + const u_char *data, size_t dlen, const char *alg) +{ + if (privkey) { + if (mm_sshkey_sign(ssh, privkey, signature, slenp, + data, dlen, alg, options.sk_provider, NULL, + ssh->compat) < 0) + fatal_f("privkey sign failed"); + } else { + if (mm_sshkey_sign(ssh, pubkey, signature, slenp, + data, dlen, alg, options.sk_provider, NULL, + ssh->compat) < 0) + fatal_f("pubkey sign failed"); + } + return 0; +} + +/* SSH2 key exchange */ +static void +do_ssh2_kex(struct ssh *ssh) +{ + char *hkalgs = NULL, *myproposal[PROPOSAL_MAX]; + const char *compression = NULL; + struct kex *kex; + int r; + + if (options.rekey_limit || options.rekey_interval) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); + + if (options.compression == COMP_NONE) + compression = "none"; + hkalgs = list_hostkey_types(); + + kex_proposal_populate_entries(ssh, myproposal, options.kex_algorithms, + options.ciphers, options.macs, compression, hkalgs); + + free(hkalgs); + + /* start key exchange */ + if ((r = kex_setup(ssh, myproposal)) != 0) + fatal_r(r, "kex_setup"); + kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos); + kex = ssh->kex; + +#ifdef WITH_OPENSSL + kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server; + kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server; + kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server; + kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server; + kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server; + kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; + kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; +# ifdef OPENSSL_HAS_ECC + kex->kex[KEX_ECDH_SHA2] = kex_gen_server; +# endif /* OPENSSL_HAS_ECC */ +#endif /* WITH_OPENSSL */ + kex->kex[KEX_C25519_SHA256] = kex_gen_server; + kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; + kex->kex[KEX_KEM_MLKEM768X25519_SHA256] = kex_gen_server; + kex->load_host_public_key=&get_hostkey_public_by_type; + kex->load_host_private_key=&get_hostkey_private_by_type; + kex->host_key_index=&get_hostkey_index; + kex->sign = sshd_hostkey_sign; + + ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &kex->done); + kex_proposal_free_entries(myproposal); + +#ifdef DEBUG_KEXDH + /* send 1st encrypted/maced/compressed message */ + if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || + (r = sshpkt_put_cstring(ssh, "markus")) != 0 || + (r = sshpkt_send(ssh)) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + fatal_fr(r, "send test"); +#endif + debug("KEX done"); +} + +/* server specific fatal cleanup */ +void +cleanup_exit(int i) +{ + _exit(i); +} diff --git a/sshd-debug.sh b/sshd-debug.sh new file mode 100755 index 00000000000..86a9b37bd15 --- /dev/null +++ b/sshd-debug.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +# ssh-debug + +# A wrapper script around sshd to invoke when debugging to debug the +# work-in-progress versions of sshd-auth and sshd-session, instead +# of debugging the installed ones that probably don't have the change +# you are working on. +# +# Placed in the Public Domain. + +unset DIR SSHD SSHD_AUTH SSHD_SESSION + +fatal() { + echo >&2 $@ + exit 1 +} + +case "$0" in +/*) DIR="`dirname $0`" ;; +./sshd-debug.sh) DIR="`pwd`" ;; +*) echo "Need full path or working directory."; exit 1 ;; +esac + +for i in sshd/obj/sshd sshd/sshd sshd; do + if [ -f "${DIR}/$i" ] && [ -x "${DIR}/$i" ]; then + SSHD="${DIR}/$i" + fi +done +[ -z "${SSHD}" ] && fatal "Could not find sshd" + +for i in sshd-auth/obj/sshd-auth sshd-auth/sshd-auth sshd-auth; do + if [ -f "${DIR}/$i" ] && [ -x "${DIR}/$i" ]; then + SSHD_AUTH="${DIR}/$i" + fi +done +[ -z "${SSHD_AUTH}" ] && fatal "Could not find sshd-auth" + +for i in sshd-session/obj/sshd-session sshd-session/sshd-session sshd-session; do + if [ -f "${DIR}/$i" ] && [ -x "${DIR}/$i" ]; then + SSHD_SESSION="${DIR}/$i" + fi +done +[ -z "${SSHD_SESSION}" ] && fatal "Could not find sshd-session" + +echo >&2 Debugging ${SSHD} auth ${SSHD_AUTH} session ${SSHD_SESSION} + +# Append SshdSessionPath and SshdAuthPath pointing to the build directory. +# If you explicitly specify these in the command line, the first-match +# keyword semantics will override these. +exec "${SSHD}" $@ \ + -oSshdAuthPath="${SSHD_AUTH}" -oSshdSessionPath="${SSHD_SESSION}" diff --git a/sshd-session.c b/sshd-session.c index bca496ec4a3..bba1eaffa39 100644 --- a/sshd-session.c +++ b/sshd-session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd-session.c,v 1.4 2024/06/26 23:16:52 deraadt Exp $ */ +/* $OpenBSD: sshd-session.c,v 1.12 2025/03/12 22:43:44 djm Exp $ */ /* * SSH2 implementation: * Privilege Separation: @@ -106,7 +106,6 @@ #include "ssh-gss.h" #endif #include "monitor_wrap.h" -#include "ssh-sandbox.h" #include "auth-options.h" #include "version.h" #include "ssherr.h" @@ -116,15 +115,16 @@ /* Re-exec fds */ #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) -#define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) -#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3) -#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) +#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 2) +#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 3) -/* Privilege separation related spawn fds */ -#ifdef WINDOWS +/* Privsep fds */ #define PRIVSEP_MONITOR_FD (STDERR_FILENO + 1) #define PRIVSEP_LOG_FD (STDERR_FILENO + 2) -#define PRIVSEP_UNAUTH_MIN_FREE_FD (PRIVSEP_LOG_FD + 1) +#define PRIVSEP_MIN_FREE_FD (STDERR_FILENO + 3) + +/* Privilege separation related spawn fds */ +#ifdef WINDOWS #define PRIVSEP_AUTH_MIN_FREE_FD (PRIVSEP_LOG_FD + 1) #endif /* WINDOWS */ @@ -162,7 +162,6 @@ int auth_sock = -1; static int have_agent = 0; #ifdef WINDOWS -int privsep_unauth_child = 0; int privsep_auth_child = 0; int io_sock_in = 0; int io_sock_out = 0; @@ -216,18 +215,34 @@ struct sshbuf *loginmsg; /* Prototypes for various functions defined later in this file. */ void destroy_sensitive_data(void); void demote_sensitive_data(void); -static void do_ssh2_kex(struct ssh *); + +/* XXX reduce to stub once postauth split */ +int +mm_is_monitor(void) +{ + /* + * m_pid is only set in the privileged part, and + * points to the unprivileged child. + */ + return (pmonitor && pmonitor->m_pid > 0); +} #ifdef WINDOWS -/* copied from sshd.c */ +/* The following methods are needed to manage sending and receiving + information between sshd-session and sshd-auth processes. + Where applicable, the methods are copied from sshd.c. +*/ static struct sshbuf* -pack_hostkeys(void) +pack_hostkeys_for_child(void) { - struct sshbuf* keybuf = NULL, * hostkeys = NULL; + /* copied from pack_hostkeys() in sshd.c, used in send_config_state() */ + struct sshbuf* m = NULL, * keybuf = NULL, * hostkeys = NULL; int r; u_int i; + size_t len; - if ((keybuf = sshbuf_new()) == NULL || + if ((m = sshbuf_new()) == NULL || + (keybuf = sshbuf_new()) == NULL || (hostkeys = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -264,20 +279,29 @@ pack_hostkeys(void) } } + if ((r = sshbuf_put_u32(m, 0)) != 0 || + (r = sshbuf_put_u8(m, 0)) != 0 || + (r = sshbuf_put_stringb(m, hostkeys)) != 0) + fatal_fr(r, "compose message"); + if ((len = sshbuf_len(m)) < 5 || len > 0xffffffff) + fatal_f("bad length %zu", len); + POKE_U32(sshbuf_mutable_ptr(m), len - 4); + sshbuf_free(keybuf); - return hostkeys; + sshbuf_free(hostkeys); + return m; } -static void -send_config_state(int fd, struct sshbuf* conf) +static struct sshbuf* +pack_config(struct sshbuf* conf) { - /* copied from send_rexec_state in sshd.c */ - struct sshbuf* m = NULL, * inc = NULL, * hostkeys = NULL; + /* copied from sshd.c */ + struct sshbuf* m = NULL, * inc = NULL; struct include_item* item = NULL; - int r, sz; + size_t len; + int r; - debug3_f("entering fd = %d config len %zu", fd, - sshbuf_len(conf)); + debug3_f("d config len %zu", sshbuf_len(conf)); if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) @@ -291,43 +315,57 @@ send_config_state(int fd, struct sshbuf* conf) fatal_fr(r, "compose includes"); } - hostkeys = pack_hostkeys(); - - /* - * Protocol from reexec master to child: - * string configuration - * uint64 timing_secret - * string host_keys[] { - * string private_key - * string public_key - * string certificate - * } - * string included_files[] { - * string selector - * string filename - * string contents - * } - */ - if ((r = sshbuf_put_stringb(m, conf)) != 0 || + if ((r = sshbuf_put_u32(m, 0)) != 0 || + (r = sshbuf_put_u8(m, 0)) != 0 || + (r = sshbuf_put_stringb(m, conf)) != 0 || (r = sshbuf_put_u64(m, options.timing_secret)) != 0 || - (r = sshbuf_put_stringb(m, hostkeys)) != 0 || (r = sshbuf_put_stringb(m, inc)) != 0) fatal_fr(r, "compose config"); -#ifndef WINDOWS - /* We need to fit the entire message inside the socket send buffer */ - sz = ROUNDUP(sshbuf_len(m) + 5, 16 * 1024); - if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof sz) == -1) - fatal_f("setsockopt SO_SNDBUF: %s", strerror(errno)); -#endif /* WINDOWS */ - if (ssh_msg_send(fd, 0, m) == -1) - error_f("ssh_msg_send failed"); + if ((len = sshbuf_len(m)) < 5 || len > 0xffffffff) + fatal_f("bad length %zu", len); + POKE_U32(sshbuf_mutable_ptr(m), len - 4); - sshbuf_free(m); sshbuf_free(inc); - sshbuf_free(hostkeys); debug3_f("done"); + return m; +} + +static void +send_config_state(int fd, struct sshbuf* conf) +{ + /* copied from send_rexec_state() in sshd.c + On Windows, uses pack_hostkeys_for_child() and pack_config() */ + struct sshbuf* keys; + u_int mlen; +#ifdef WINDOWS + struct sshbuf* config = pack_config(conf); +#else + pid_t pid; + + if ((pid = fork()) == -1) + fatal_f("fork failed: %s", strerror(errno)); + if (pid != 0) + return; +#endif /* !WINDOWS */ + debug3_f("entering fd = %d config len %zu", fd, + sshbuf_len(config)); + + mlen = sshbuf_len(config); + if (atomicio(vwrite, fd, sshbuf_mutable_ptr(config), mlen) != mlen) + error_f("write: %s", strerror(errno)); + + keys = pack_hostkeys_for_child(); + mlen = sshbuf_len(keys); + if (atomicio(vwrite, fd, sshbuf_mutable_ptr(keys), mlen) != mlen) + error_f("write: %s", strerror(errno)); + + sshbuf_free(keys); + debug3_f("done"); +#ifndef WINDOWS + exit(0); +#endif /* !WINDOWS */ } static void @@ -469,61 +507,8 @@ send_hostkeys_state(int fd) sshbuf_free(m); } -static void -recv_hostkeys_state(int fd) -{ - struct sshbuf* m; - u_char* cp, ver; - struct sshkey* key = NULL; - const u_char* blob; - size_t blen; - int r; - u_int32_t num_host_key_files; - - debug3("%s: entering fd = %d", __func__, fd); - - if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); - if (ssh_msg_recv(fd, m) == -1) - fatal("%s: ssh_msg_recv failed", __func__); - if ((r = sshbuf_get_u8(m, &ver)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - if (ver != 0) - fatal("%s: rexec version mismatch", __func__); - - if ((r = sshbuf_get_u32(m, &num_host_key_files)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - sensitive_data.host_keys = xcalloc(num_host_key_files, sizeof(struct sshkey*)); - sensitive_data.host_pubkeys = xcalloc(num_host_key_files, sizeof(struct sshkey*)); - sensitive_data.host_certificates = xcalloc(num_host_key_files, sizeof(struct sshkey*)); - for (int i = 0; i < num_host_key_files; i++) { - if ((r = sshbuf_get_string_direct(m, &blob, &blen)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - sensitive_data.host_pubkeys[i] = NULL; - sensitive_data.host_keys[i] = NULL; - - if (blen) { - sshkey_from_blob(blob, blen, &key); - sensitive_data.host_pubkeys[i] = key; - } - } - - for (int i = 0; i < num_host_key_files; i++) { - if ((r = sshbuf_get_string_direct(m, &blob, &blen)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - sensitive_data.host_certificates[i] = NULL; - if (blen) { - sshkey_from_blob(blob, blen, &key); - sensitive_data.host_certificates[i] = key; - } - } - - sshbuf_free(m); - debug3("%s: done", __func__); -} - static char** -privsep_child_cmdline(int authenticated) +privsep_child_cmdline() { char** argv = saved_argv; int argc = 0; @@ -543,10 +528,7 @@ privsep_child_cmdline(int authenticated) argc = saved_argc; } - if (authenticated) - argv[argc] = "-z"; - else - argv[argc] = "-y"; + argv[argc] = "-z"; return argv; } @@ -560,9 +542,7 @@ privsep_child_cmdline(int authenticated) static void grace_alarm_handler(int sig) { -#ifdef WINDOWS - // TODO: figure out if we need to kill any child processes -#else /* WINDOWS */ +#ifndef WINDOWS /* * Try to kill any processes that we have spawned, E.g. authorized * keys command helpers or privsep children. @@ -574,7 +554,9 @@ grace_alarm_handler(int sig) memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; sigfillset(&sa.sa_mask); +#if defined(SA_RESTART) sa.sa_flags = SA_RESTART; +#endif (void)sigaction(SIGTERM, &sa, NULL); kill(0, SIGTERM); } @@ -642,41 +624,41 @@ reseed_prngs(void) explicit_bzero(rnd, sizeof(rnd)); } -static void -privsep_preauth_child(void) +struct sshbuf * +pack_hostkeys(void) { - gid_t gidset[1]; - - /* Enable challenge-response authentication for privilege separation */ - privsep_challenge_enable(); - -#ifdef GSSAPI - /* Cache supported mechanism OIDs for later use */ - ssh_gssapi_prepare_supported_oids(); -#endif - - reseed_prngs(); + struct sshbuf *keybuf = NULL, *hostkeys = NULL; + int r; + u_int i; - /* Demote the private keys to public keys. */ - demote_sensitive_data(); + if ((hostkeys = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); - /* Demote the child */ - if (privsep_chroot) { - /* Change our root directory */ - if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) - fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, - strerror(errno)); - if (chdir("/") == -1) - fatal("chdir(\"/\"): %s", strerror(errno)); - - /* Drop our privileges */ - debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid, - (u_int)privsep_pw->pw_gid); - gidset[0] = privsep_pw->pw_gid; - if (setgroups(1, gidset) == -1) - fatal("setgroups: %.100s", strerror(errno)); - permanently_set_uid(privsep_pw); + /* pack hostkeys into a string. Empty key slots get empty strings */ + for (i = 0; i < options.num_host_key_files; i++) { + /* public key */ + if (sensitive_data.host_pubkeys[i] != NULL) { + if ((r = sshkey_puts(sensitive_data.host_pubkeys[i], + hostkeys)) != 0) + fatal_fr(r, "compose hostkey public"); + } else { + if ((r = sshbuf_put_string(hostkeys, NULL, 0)) != 0) + fatal_fr(r, "compose hostkey empty public"); + } + /* cert */ + if (sensitive_data.host_certificates[i] != NULL) { + if ((r = sshkey_puts( + sensitive_data.host_certificates[i], + hostkeys)) != 0) + fatal_fr(r, "compose host cert"); + } else { + if ((r = sshbuf_put_string(hostkeys, NULL, 0)) != 0) + fatal_fr(r, "compose host cert empty"); + } } + + sshbuf_free(keybuf); + return hostkeys; } static int @@ -684,7 +666,6 @@ privsep_preauth(struct ssh *ssh) { int status, r; pid_t pid; - struct ssh_sandbox *box = NULL; /* Set up unprivileged child process to deal with network data */ pmonitor = monitor_init(); @@ -699,25 +680,6 @@ privsep_preauth(struct ssh *ssh) authctxt->valid = 1; return 1; } - else if (privsep_unauth_child) { - close(pmonitor->m_sendfd); - close(pmonitor->m_log_recvfd); - close(pmonitor->m_recvfd); - close(pmonitor->m_log_sendfd); - - pmonitor->m_recvfd = PRIVSEP_MONITOR_FD; - pmonitor->m_log_sendfd = PRIVSEP_LOG_FD; - - fcntl(pmonitor->m_recvfd, F_SETFD, FD_CLOEXEC); - fcntl(pmonitor->m_log_sendfd, F_SETFD, FD_CLOEXEC); - - /* Arrange for logging to be sent to the monitor */ - set_log_handler(mm_log_handler, pmonitor); - - privsep_preauth_child(); - setproctitle("%s", "[net]"); - return 0; - } else { /* parent */ posix_spawn_file_actions_t actions; @@ -728,13 +690,10 @@ privsep_preauth(struct ssh *ssh) posix_spawn_file_actions_adddup2(&actions, pmonitor->m_log_sendfd, PRIVSEP_LOG_FD) != 0 ) fatal("posix_spawn initialization failed"); - { - char** argv = privsep_child_cmdline(0); - if (__posix_spawn_asuser(&pid, argv[0], &actions, NULL, argv, NULL, SSH_PRIVSEP_USER) != 0) - fatal("%s, fork of unprivileged child failed", __func__); + if (__posix_spawn_asuser(&pid, options.sshd_auth_path, &actions, NULL, saved_argv, NULL, SSH_PRIVSEP_USER) != 0) + fatal("%s, fork of unprivileged child failed", __func__); - posix_spawn_file_actions_destroy(&actions); - } + posix_spawn_file_actions_destroy(&actions); debug2("Network child is on pid %ld", (long)pid); @@ -750,8 +709,6 @@ privsep_preauth(struct ssh *ssh) close(pmonitor->m_recvfd); close(pmonitor->m_log_sendfd); - send_config_state(pmonitor->m_sendfd, cfg); - send_idexch_state(ssh, pmonitor->m_sendfd); monitor_child_preauth(ssh, pmonitor); while (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) @@ -764,12 +721,9 @@ privsep_preauth(struct ssh *ssh) return 1; } #else - if (use_privsep == PRIVSEP_ON) - box = ssh_sandbox_init(pmonitor); - pid = fork(); - if (pid == -1) { + if ((pid = fork()) == -1) fatal("fork of unprivileged child failed"); - } else if (pid != 0) { + else if (pid != 0) { debug2("Network child is on pid %ld", (long)pid); pmonitor->m_pid = pid; @@ -780,8 +734,6 @@ privsep_preauth(struct ssh *ssh) have_agent = 0; } } - if (box != NULL) - ssh_sandbox_parent_preauth(box, pid); monitor_child_preauth(ssh, pmonitor); /* Wait for the child's exit status */ @@ -800,23 +752,46 @@ privsep_preauth(struct ssh *ssh) } else if (WIFSIGNALED(status)) fatal_f("preauth child terminated by signal %d", WTERMSIG(status)); - if (box != NULL) - ssh_sandbox_parent_finish(box); return 1; } else { /* child */ close(pmonitor->m_sendfd); close(pmonitor->m_log_recvfd); - /* Arrange for logging to be sent to the monitor */ - set_log_handler(mm_log_handler, pmonitor); - - privsep_preauth_child(); - setproctitle("%s", "[net]"); - if (box != NULL) - ssh_sandbox_child(box); + /* + * Arrange unpriv-preauth child process fds: + * 0, 1 network socket + * 2 optional stderr + * 3 reserved + * 4 monitor message socket + * 5 monitor logging socket + * + * We know that the monitor sockets will have fds > 4 because + * of the reserved fds in main() + */ - return 0; + if (ssh_packet_get_connection_in(ssh) != STDIN_FILENO && + dup2(ssh_packet_get_connection_in(ssh), STDIN_FILENO) == -1) + fatal("dup2 stdin failed: %s", strerror(errno)); + if (ssh_packet_get_connection_out(ssh) != STDOUT_FILENO && + dup2(ssh_packet_get_connection_out(ssh), + STDOUT_FILENO) == -1) + fatal("dup2 stdout failed: %s", strerror(errno)); + /* leave stderr as-is */ + log_redirect_stderr_to(NULL); /* dup can clobber log fd */ + if (pmonitor->m_recvfd != PRIVSEP_MONITOR_FD && + dup2(pmonitor->m_recvfd, PRIVSEP_MONITOR_FD) == -1) + fatal("dup2 monitor fd: %s", strerror(errno)); + if (pmonitor->m_log_sendfd != PRIVSEP_LOG_FD && + dup2(pmonitor->m_log_sendfd, PRIVSEP_LOG_FD) == -1) + fatal("dup2 log fd: %s", strerror(errno)); + closefrom(PRIVSEP_MIN_FREE_FD); + + saved_argv[0] = options.sshd_auth_path; + execv(options.sshd_auth_path, saved_argv); + + fatal_f("exec of %s failed: %s", + options.sshd_auth_path, strerror(errno)); } #endif } @@ -853,19 +828,15 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) if (posix_spawn_file_actions_init(&actions) != 0 || posix_spawn_file_actions_adddup2(&actions, io_sock_in, STDIN_FILENO) != 0 || posix_spawn_file_actions_adddup2(&actions, io_sock_out, STDOUT_FILENO) != 0 || -#ifdef WINDOWS /*Allow authenticated child process to foward log messages to parent for processing*/ posix_spawn_file_actions_adddup2(&actions, pmonitor->m_log_sendfd, PRIVSEP_LOG_FD) != 0 || -#endif posix_spawn_file_actions_adddup2(&actions, pmonitor->m_recvfd, PRIVSEP_MONITOR_FD) != 0) fatal("posix_spawn initialization failed"); - { - char** argv = privsep_child_cmdline(1); - if (__posix_spawn_asuser(&pmonitor->m_pid, argv[0], &actions, NULL, argv, NULL, authctxt->pw->pw_name) != 0) - fatal("fork of unprivileged child failed"); - posix_spawn_file_actions_destroy(&actions); - } + char** argv = privsep_child_cmdline(); + if (__posix_spawn_asuser(&pmonitor->m_pid, argv[0], &actions, NULL, argv, NULL, authctxt->pw->pw_name) != 0) + fatal("fork of unprivileged child failed"); + posix_spawn_file_actions_destroy(&actions); verbose("User child is on pid %ld", (long)pmonitor->m_pid); send_config_state(pmonitor->m_sendfd, cfg); @@ -894,7 +865,6 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) close(pmonitor->m_log_sendfd); pmonitor->m_log_sendfd = PRIVSEP_LOG_FD; fcntl(pmonitor->m_log_sendfd, F_SETFD, FD_CLOEXEC); - /* Arrange for logging to be sent to the monitor */ set_log_handler(mm_log_handler, pmonitor); #endif @@ -947,79 +917,6 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) #endif } -static void -append_hostkey_type(struct sshbuf *b, const char *s) -{ - int r; - - if (match_pattern_list(s, options.hostkeyalgorithms, 0) != 1) { - debug3_f("%s key not permitted by HostkeyAlgorithms", s); - return; - } - if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) > 0 ? "," : "", s)) != 0) - fatal_fr(r, "sshbuf_putf"); -} - -static char * -list_hostkey_types(void) -{ - struct sshbuf *b; - struct sshkey *key; - char *ret; - u_int i; - - if ((b = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); - for (i = 0; i < options.num_host_key_files; i++) { - key = sensitive_data.host_keys[i]; - if (key == NULL) - key = sensitive_data.host_pubkeys[i]; - if (key == NULL) - continue; - switch (key->type) { - case KEY_RSA: - /* for RSA we also support SHA2 signatures */ - append_hostkey_type(b, "rsa-sha2-512"); - append_hostkey_type(b, "rsa-sha2-256"); - /* FALLTHROUGH */ - case KEY_DSA: - case KEY_ECDSA: - case KEY_ED25519: - case KEY_ECDSA_SK: - case KEY_ED25519_SK: - case KEY_XMSS: - append_hostkey_type(b, sshkey_ssh_name(key)); - break; - } - /* If the private key has a cert peer, then list that too */ - key = sensitive_data.host_certificates[i]; - if (key == NULL) - continue; - switch (key->type) { - case KEY_RSA_CERT: - /* for RSA we also support SHA2 signatures */ - append_hostkey_type(b, - "rsa-sha2-512-cert-v01@openssh.com"); - append_hostkey_type(b, - "rsa-sha2-256-cert-v01@openssh.com"); - /* FALLTHROUGH */ - case KEY_DSA_CERT: - case KEY_ECDSA_CERT: - case KEY_ED25519_CERT: - case KEY_ECDSA_SK_CERT: - case KEY_ED25519_SK_CERT: - case KEY_XMSS_CERT: - append_hostkey_type(b, sshkey_ssh_name(key)); - break; - } - } - if ((ret = sshbuf_dup_string(b)) == NULL) - fatal_f("sshbuf_dup_string failed"); - sshbuf_free(b); - debug_f("%s", ret); - return ret; -} - static struct sshkey * get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) { @@ -1247,6 +1144,8 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp) if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); + + /* receive config */ if (ssh_msg_recv(fd, m) == -1) fatal_f("ssh_msg_recv failed"); if ((r = sshbuf_get_u8(m, &ver)) != 0) @@ -1255,7 +1154,6 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp) fatal_f("rexec version mismatch"); if ((r = sshbuf_get_string(m, &cp, &len)) != 0 || /* XXX _direct */ (r = sshbuf_get_u64(m, timing_secretp)) != 0 || - (r = sshbuf_froms(m, &hostkeys)) != 0 || (r = sshbuf_get_stringb(m, inc)) != 0) fatal_fr(r, "parse config"); @@ -1273,6 +1171,13 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp) TAILQ_INSERT_TAIL(&includes, item, entry); } + /* receive hostkeys */ + sshbuf_reset(m); + if (ssh_msg_recv(fd, m) == -1) + fatal_f("ssh_msg_recv failed"); + if ((r = sshbuf_get_u8(m, NULL)) != 0 || + (r = sshbuf_froms(m, &hostkeys)) != 0) + fatal_fr(r, "parse config"); parse_hostkeys(hostkeys); free(cp); @@ -1321,7 +1226,6 @@ check_ip_options(struct ssh *ssh) fatal("Connection from %.100s port %d with IP opts: %.800s", ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text); } - return; #endif /* IP_OPTIONS */ } @@ -1374,7 +1278,11 @@ main(int ac, char **av) struct ssh *ssh = NULL; extern char *optarg; extern int optind; +#ifdef WINDOWS int r, opt, on = 1, remote_port; +#else + int devnull, r, opt, on = 1, remote_port; +#endif /* WINDOWS */ int sock_in = -1, sock_out = -1, rexeced_flag = 0, have_key = 0; const char *remote_ip, *rdomain; char *line, *laddr, *logfile = NULL; @@ -1385,7 +1293,7 @@ main(int ac, char **av) struct connection_info *connection_info = NULL; sigset_t sigmask; uint64_t timing_secret = 0; - + struct itimerval itv; sigemptyset(&sigmask); sigprocmask(SIG_SETMASK, &sigmask, NULL); @@ -1527,10 +1435,6 @@ main(int ac, char **av) SSH_RELEASE, SSH_OPENSSL_VERSION); exit(0); #ifdef WINDOWS - case 'y': - privsep_unauth_child = 1; - logfile = NULL; - break; case 'z': privsep_auth_child = 1; logfile = NULL; @@ -1548,17 +1452,14 @@ main(int ac, char **av) exit(1); } - debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); #ifdef WINDOWS - if (!rexeced_flag && !privsep_unauth_child && !privsep_auth_child) + if (!rexeced_flag && !privsep_auth_child) #else /* WINDOWS */ if (!rexeced_flag) #endif /* WINDOWS */ fatal("sshd-session should not be executed directly"); #ifdef WINDOWS - if (privsep_unauth_child) - closefrom(PRIVSEP_UNAUTH_MIN_FREE_FD); - else if (privsep_auth_child) + if (privsep_auth_child) closefrom(PRIVSEP_AUTH_MIN_FREE_FD); else closefrom(REEXEC_MIN_FREE_FD); @@ -1566,6 +1467,16 @@ main(int ac, char **av) closefrom(REEXEC_MIN_FREE_FD); #endif /* WINDOWS */ + platform_pre_session_start(); +#ifndef WINDOWS + /* Reserve fds we'll need later for reexec things */ + if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) + fatal("open %s: %s", _PATH_DEVNULL, strerror(errno)); + while (devnull < PRIVSEP_MIN_FREE_FD) { + if ((devnull = dup(devnull)) == -1) + fatal("dup %s: %s", _PATH_DEVNULL, strerror(errno)); + } +#endif /* !WINDOWS */ seed_rng(); /* If requested, redirect the logs to the specified logfile. */ @@ -1592,29 +1503,31 @@ main(int ac, char **av) SYSLOG_FACILITY_AUTH : options.log_facility, log_stderr || !inetd_flag || debug_flag); - debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); - /* Fetch our configuration */ if ((cfg = sshbuf_new()) == NULL) fatal("sshbuf_new config buf failed"); setproctitle("%s", "[rexeced]"); #ifdef WINDOWS - if (privsep_unauth_child || privsep_auth_child) { + if (privsep_auth_child) { recv_rexec_state(PRIVSEP_MONITOR_FD, cfg, &timing_secret); //TODO - should starup_pipe be closed as above ?B } else { recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg, &timing_secret); - close(REEXEC_CONFIG_PASS_FD); } #else /* WINDOWS */ recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg, &timing_secret); - close(REEXEC_CONFIG_PASS_FD); #endif /* WINDOWS */ parse_server_config(&options, "rexec", cfg, &includes, NULL, 1); /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); options.timing_secret = timing_secret; + /* Reinit logging in case config set Level, Facility or Verbose. */ + log_init(__progname, options.log_level, options.log_facility, + log_stderr || !inetd_flag || debug_flag); + + debug("sshd-session version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); + /* Store privilege separation user for later use if required. */ privsep_chroot = (getuid() == 0 || geteuid() == 0); if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) { @@ -1629,19 +1542,24 @@ main(int ac, char **av) endpwent(); #ifdef WINDOWS - if (!debug_flag && !privsep_unauth_child && !privsep_auth_child) { + if (!debug_flag && !inetd_flag && !privsep_auth_child) { #else /* WINDOWS */ - if (!debug_flag) { + if (!debug_flag && !inetd_flag) { #endif /* WINDOWS */ - startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); - close(REEXEC_STARTUP_PIPE_FD); + if ((startup_pipe = dup(REEXEC_CONFIG_PASS_FD)) == -1) + fatal("internal error: no startup pipe"); + /* * Signal parent that this child is at a point where * they can go away if they have a SIGHUP pending. */ (void)atomicio(vwrite, startup_pipe, "\0", 1); } - +#ifndef WINDOWS + /* close the fd, but keep the slot reserved */ + if (dup2(devnull, REEXEC_CONFIG_PASS_FD) == -1) + fatal("dup2 devnull->config fd: %s", strerror(errno)); +#endif /* !WINDOWS */ /* Check that options are sensible */ if (options.authorized_keys_command_user == NULL && (options.authorized_keys_command != NULL && @@ -1812,7 +1730,7 @@ main(int ac, char **av) rdomain = ssh_packet_rdomain_in(ssh); - if (privsep_unauth_child || privsep_auth_child) { + if (privsep_auth_child) { recv_idexch_state(ssh, PRIVSEP_MONITOR_FD); goto idexch_done; } @@ -1838,8 +1756,17 @@ main(int ac, char **av) * are about to discover the bug. */ ssh_signal(SIGALRM, grace_alarm_handler); - if (!debug_flag) - alarm(options.login_grace_time); + if (!debug_flag && options.login_grace_time > 0) { + int ujitter = arc4random_uniform(4 * 1000000); + + timerclear(&itv.it_interval); + itv.it_value.tv_sec = options.login_grace_time; + itv.it_value.tv_sec += ujitter / 1000000; + itv.it_value.tv_usec = ujitter % 1000000; + + if (setitimer(ITIMER_REAL, &itv, NULL) == -1) + fatal("login grace time setitimer failed"); + } if ((r = kex_exchange_identification(ssh, -1, options.version_addendum)) != 0) @@ -1871,27 +1798,19 @@ main(int ac, char **av) fatal("sshbuf_new loginmsg failed"); auth_debug_reset(); - if (privsep_preauth(ssh) == 1) - goto authenticated; + if (privsep_preauth(ssh) != 1) + fatal("privsep_preauth failed"); - /* perform the key exchange */ - /* authenticate user and start session */ - do_ssh2_kex(ssh); - do_authentication2(ssh); + /* Now user is authenticated */ - /* - * The unprivileged child now transfers the current keystate and exits. - */ - mm_send_keystate(ssh, pmonitor); - ssh_packet_clear_keys(ssh); - exit(0); - - authenticated: /* * Cancel the alarm we set to limit the time taken for * authentication. */ - alarm(0); + timerclear(&itv.it_interval); + timerclear(&itv.it_value); + if (setitimer(ITIMER_REAL, &itv, NULL) == -1) + fatal("login grace time clear failed"); ssh_signal(SIGALRM, SIG_DFL); authctxt->authenticated = 1; if (startup_pipe != -1) { @@ -1980,67 +1899,6 @@ sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, return 0; } -/* SSH2 key exchange */ -static void -do_ssh2_kex(struct ssh *ssh) -{ - char *hkalgs = NULL, *myproposal[PROPOSAL_MAX]; - const char *compression = NULL; - struct kex *kex; - int r; - - if (options.rekey_limit || options.rekey_interval) - ssh_packet_set_rekey_limits(ssh, options.rekey_limit, - options.rekey_interval); - - if (options.compression == COMP_NONE) - compression = "none"; - hkalgs = list_hostkey_types(); - - kex_proposal_populate_entries(ssh, myproposal, options.kex_algorithms, - options.ciphers, options.macs, compression, hkalgs); - - free(hkalgs); - - /* start key exchange */ - if ((r = kex_setup(ssh, myproposal)) != 0) - fatal_r(r, "kex_setup"); - kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos); - kex = ssh->kex; - -#ifdef WITH_OPENSSL - kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server; - kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server; - kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server; - kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server; - kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server; - kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; - kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; - #ifdef OPENSSL_HAS_ECC - kex->kex[KEX_ECDH_SHA2] = kex_gen_server; - #endif -#endif - kex->kex[KEX_C25519_SHA256] = kex_gen_server; - kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; - kex->load_host_public_key=&get_hostkey_public_by_type; - kex->load_host_private_key=&get_hostkey_private_by_type; - kex->host_key_index=&get_hostkey_index; - kex->sign = sshd_hostkey_sign; - - ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &kex->done); - kex_proposal_free_entries(myproposal); - -#ifdef DEBUG_KEXDH - /* send 1st encrypted/maced/compressed message */ - if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || - (r = sshpkt_put_cstring(ssh, "markus")) != 0 || - (r = sshpkt_send(ssh)) != 0 || - (r = ssh_packet_write_wait(ssh)) != 0) - fatal_fr(r, "send test"); -#endif - debug("KEX done"); -} - /* server specific fatal cleanup */ void cleanup_exit(int i) @@ -2059,13 +1917,13 @@ cleanup_exit(int i) } } } - /* Override default fatal exit value when auth was attempted */ - if (i == 255 && auth_attempted) - _exit(EXIT_AUTH_ATTEMPTED); #ifdef SSH_AUDIT_EVENTS /* done after do_cleanup so it can cancel the PAM auth 'thread' */ if (the_active_state != NULL && mm_is_monitor()) audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif + /* Override default fatal exit value when auth was attempted */ + if (i == 255 && auth_attempted) + _exit(EXIT_AUTH_ATTEMPTED); _exit(i); } diff --git a/sshd.0 b/sshd.0 index c7de2d31188..23e28bee2df 100644 --- a/sshd.0 +++ b/sshd.0 @@ -40,7 +40,9 @@ DESCRIPTION The keywords are M-bM-^@M-^\addrM-bM-^@M-^], M-bM-^@M-^\userM-bM-^@M-^], M-bM-^@M-^\hostM-bM-^@M-^], M-bM-^@M-^\laddrM-bM-^@M-^], M-bM-^@M-^\lportM-bM-^@M-^], and M-bM-^@M-^\rdomainM-bM-^@M-^] and correspond to source address, user, resolved source host name, local address, local port number and routing domain - respectively. + respectively. Additionally the M-bM-^@M-^\invalid-userM-bM-^@M-^] flag (which does + not take a value argument) may be specified to simulate a + connection from an unrecognised username. -c host_certificate_file Specifies a path to a certificate file to identify sshd during @@ -682,4 +684,4 @@ AUTHORS versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -OpenBSD 7.5 June 17, 2024 OpenBSD 7.5 +OpenBSD 7.6 September 15, 2024 OpenBSD 7.6 diff --git a/sshd.8 b/sshd.8 index c0f095ca446..08ebf53a128 100644 --- a/sshd.8 +++ b/sshd.8 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.326 2024/06/17 08:30:29 djm Exp $ -.Dd $Mdocdate: June 17 2024 $ +.\" $OpenBSD: sshd.8,v 1.327 2024/09/15 01:19:56 djm Exp $ +.Dd $Mdocdate: September 15 2024 $ .Dt SSHD 8 .Os .Sh NAME @@ -115,6 +115,10 @@ and .Dq rdomain and correspond to source address, user, resolved source host name, local address, local port number and routing domain respectively. +Additionally the +.Dq invalid-user +flag (which does not take a value argument) may be specified to simulate +a connection from an unrecognised username. .It Fl c Ar host_certificate_file Specifies a path to a certificate file to identify .Nm diff --git a/sshd.c b/sshd.c index 3124748a344..0e920f0488f 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.609 2024/06/27 23:01:15 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.617 2025/04/07 08:12:22 dtucker Exp $ */ /* * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. * Copyright (c) 2002 Niels Provos. All rights reserved. @@ -38,6 +38,9 @@ #include "openbsd-compat/sys-tree.h" #include "openbsd-compat/sys-queue.h" #include +#ifndef WINDOWS +#include +#endif /* WINDOWS */ #include #include @@ -52,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -95,24 +99,18 @@ #include "sk-api.h" #include "addr.h" #include "srclimit.h" +#include "atomicio.h" /* Re-exec fds */ #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) -#define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) -#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3) -#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) +#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 2) +#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 3) /* Privilege separation related spawn fds */ #define PRIVSEP_MONITOR_FD (STDERR_FILENO + 1) #define PRIVSEP_LOG_FD (STDERR_FILENO + 2) #define PRIVSEP_UNAUTH_MIN_FREE_FD (PRIVSEP_LOG_FD + 1) -#ifdef WINDOWS -#define PRIVSEP_AUTH_MIN_FREE_FD (PRIVSEP_LOG_FD + 1) -#else -#define PRIVSEP_AUTH_MIN_FREE_FD (PRIVSEP_MONITOR_FD + 1) -#endif - extern char *__progname; /* Server configuration options. */ @@ -125,9 +123,6 @@ ServerOptions options; * the first connection. */ int debug_flag = 0; -#ifdef WINDOWS -debug_startup_p = -1; -#endif /* WINDOWS */ /* Saved arguments to main(). */ static char **saved_argv; @@ -203,13 +198,15 @@ struct early_child { struct xaddr addr; int have_addr; int status, have_status; + struct sshbuf *config; + struct sshbuf *keys; }; static struct early_child *children; static int children_active; -static int startup_pipe = -1; /* in child */ /* sshd_config buffer */ struct sshbuf *cfg; +struct sshbuf *config; /* packed */ /* Included files from the configuration file */ struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); @@ -260,7 +257,10 @@ child_register(int pipefd, int sockfd) struct sockaddr *sa = (struct sockaddr *)&addr; for (i = 0; i < options.max_startups; i++) { - if (children[i].pipefd != -1 || children[i].pid > 0) + if (children[i].pipefd != -1 || + children[i].config != NULL || + children[i].keys != NULL || + children[i].pid > 0) continue; child = &(children[i]); break; @@ -271,6 +271,8 @@ child_register(int pipefd, int sockfd) } child->pipefd = pipefd; child->early = 1; + if ((child->config = sshbuf_fromb(config)) == NULL) + fatal_f("sshbuf_fromb failed"); /* record peer address, if available */ if (getpeername(sockfd, sa, &addrlen) == 0 && addr_sa_to_xaddr(sa, addrlen, &child->addr) == 0) @@ -284,7 +286,7 @@ child_register(int pipefd, int sockfd) } else { laddr = get_local_ipaddr(sockfd); raddr = get_peer_ipaddr(sockfd); - xasprintf(&child->id, "connection from %s to %s", laddr, raddr); + xasprintf(&child->id, "connection from %s to %s", raddr, laddr); } free(laddr); free(raddr); @@ -304,6 +306,8 @@ child_finish(struct early_child *child) fatal_f("internal error: children_active underflow"); if (child->pipefd != -1) close(child->pipefd); + sshbuf_free(child->config); + sshbuf_free(child->keys); free(child->id); memset(child, '\0', sizeof(*child)); child->pipefd = -1; @@ -357,6 +361,16 @@ child_reap(struct early_child *child) { LogLevel level = SYSLOG_LEVEL_DEBUG1; int was_crash, penalty_type = SRCLIMIT_PENALTY_NONE; + const char *child_status; + + if (child->config) + child_status = " (sending config)"; + else if (child->keys) + child_status = " (sending keys)"; + else if (child->early) + child_status = " (early)"; + else + child_status = ""; /* Log exit information */ if (WIFSIGNALED(child->status)) { @@ -368,47 +382,50 @@ child_reap(struct early_child *child) level = SYSLOG_LEVEL_ERROR; do_log2(level, "session process %ld for %s killed by " "signal %d%s", (long)child->pid, child->id, - WTERMSIG(child->status), child->early ? " (early)" : ""); + WTERMSIG(child->status), child_status); if (was_crash) penalty_type = SRCLIMIT_PENALTY_CRASH; } else if (!WIFEXITED(child->status)) { penalty_type = SRCLIMIT_PENALTY_CRASH; error("session process %ld for %s terminated abnormally, " "status=0x%x%s", (long)child->pid, child->id, child->status, - child->early ? " (early)" : ""); + child_status); } else { /* Normal exit. We care about the status */ switch (WEXITSTATUS(child->status)) { case 0: debug3_f("preauth child %ld for %s completed " - "normally %s", (long)child->pid, child->id, - child->early ? " (early)" : ""); + "normally%s", (long)child->pid, child->id, + child_status); break; case EXIT_LOGIN_GRACE: penalty_type = SRCLIMIT_PENALTY_GRACE_EXCEEDED; logit("Timeout before authentication for %s, " "pid = %ld%s", child->id, (long)child->pid, - child->early ? " (early)" : ""); + child_status); break; case EXIT_CHILD_CRASH: penalty_type = SRCLIMIT_PENALTY_CRASH; logit("Session process %ld unpriv child crash for %s%s", - (long)child->pid, child->id, - child->early ? " (early)" : ""); + (long)child->pid, child->id, child_status); break; case EXIT_AUTH_ATTEMPTED: penalty_type = SRCLIMIT_PENALTY_AUTHFAIL; debug_f("preauth child %ld for %s exited " - "after unsuccessful auth attempt %s", - (long)child->pid, child->id, - child->early ? " (early)" : ""); + "after unsuccessful auth attempt%s", + (long)child->pid, child->id, child_status); + break; + case EXIT_CONFIG_REFUSED: + penalty_type = SRCLIMIT_PENALTY_REFUSECONNECTION; + debug_f("preauth child %ld for %s prohibited by" + "RefuseConnection%s", + (long)child->pid, child->id, child_status); break; default: penalty_type = SRCLIMIT_PENALTY_NOAUTH; debug_f("preauth child %ld for %s exited " "with status %d%s", (long)child->pid, child->id, - WEXITSTATUS(child->status), - child->early ? " (early)" : ""); + WEXITSTATUS(child->status), child_status); break; } } @@ -471,6 +488,7 @@ static void show_info(void) { int i; + const char *child_status; /* XXX print listening sockets here too */ if (children == NULL) @@ -479,9 +497,16 @@ show_info(void) for (i = 0; i < options.max_startups; i++) { if (children[i].pipefd == -1 && children[i].pid <= 0) continue; + if (children[i].config) + child_status = " (sending config)"; + else if (children[i].keys) + child_status = " (sending keys)"; + else if (children[i].early) + child_status = " (early)"; + else + child_status = ""; logit("child %d: fd=%d pid=%ld %s%s", i, children[i].pipefd, - (long)children[i].pid, children[i].id, - children[i].early ? " (early)" : ""); + (long)children[i].pid, children[i].id, child_status); } srclimit_penalty_info(); } @@ -543,60 +568,6 @@ main_sigchld_handler(int sig) received_sigchld = 1; } -#ifdef WINDOWS -static void -recv_hostkeys_state(int fd) -{ - struct sshbuf *m; - u_char *cp, ver; - struct sshkey *key = NULL; - const u_char *blob; - size_t blen; - int r; - u_int32_t num_host_key_files; - - debug3("%s: entering fd = %d", __func__, fd); - - if ((m = sshbuf_new()) == NULL) - fatal("%s: sshbuf_new failed", __func__); - if (ssh_msg_recv(fd, m) == -1) - fatal("%s: ssh_msg_recv failed", __func__); - if ((r = sshbuf_get_u8(m, &ver)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - if (ver != 0) - fatal("%s: rexec version mismatch", __func__); - - if ((r = sshbuf_get_u32(m, &num_host_key_files)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - sensitive_data.host_keys = xcalloc(num_host_key_files, sizeof(struct sshkey *)); - sensitive_data.host_pubkeys = xcalloc(num_host_key_files, sizeof(struct sshkey *)); - sensitive_data.host_certificates = xcalloc(num_host_key_files, sizeof(struct sshkey *)); - for (int i = 0; i < num_host_key_files; i++) { - if ((r = sshbuf_get_string_direct(m, &blob, &blen)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - sensitive_data.host_pubkeys[i] = NULL; - sensitive_data.host_keys[i] = NULL; - - if (blen) { - sshkey_from_blob(blob, blen, &key); - sensitive_data.host_pubkeys[i] = key; - } - } - - for (int i = 0; i < num_host_key_files; i++) { - if ((r = sshbuf_get_string_direct(m, &blob, &blen)) != 0) - fatal("%s: buffer error: %s", __func__, ssh_err(r)); - sensitive_data.host_certificates[i] = NULL; - if (blen) { - sshkey_from_blob(blob, blen, &key); - sensitive_data.host_certificates[i] = key; - } - } - - sshbuf_free(m); - debug3("%s: done", __func__); -} -#endif /* * returns 1 if connection should be dropped, 0 otherwise. * dropping starts at connection #max_startups_begin with a probability @@ -635,59 +606,51 @@ should_drop_connection(int startups) static int drop_connection(int sock, int startups, int notify_pipe) { + static struct log_ratelimit_ctx ratelimit_maxstartups; + static struct log_ratelimit_ctx ratelimit_penalty; + static int init_done; char *laddr, *raddr; - const char *reason = NULL, msg[] = "Not allowed at this time\r\n"; - static time_t last_drop, first_drop; - static u_int ndropped; - LogLevel drop_level = SYSLOG_LEVEL_VERBOSE; - time_t now; - - if (!srclimit_penalty_check_allow(sock, &reason)) { - drop_level = SYSLOG_LEVEL_INFO; - goto handle; + const char *reason = NULL, *subreason = NULL; + const char msg[] = "Not allowed at this time\r\n"; + struct log_ratelimit_ctx *rl = NULL; + int ratelimited; + u_int ndropped; + + if (!init_done) { + init_done = 1; + log_ratelimit_init(&ratelimit_maxstartups, 4, 60, 20, 5*60); + log_ratelimit_init(&ratelimit_penalty, 8, 60, 30, 2*60); } - now = monotime(); - if (!should_drop_connection(startups) && - srclimit_check_allow(sock, notify_pipe) == 1) { - if (last_drop != 0 && - startups < options.max_startups_begin - 1) { - /* XXX maybe need better hysteresis here */ - logit("exited MaxStartups throttling after %s, " - "%u connections dropped", - fmt_timeframe(now - first_drop), ndropped); - last_drop = 0; - } - return 0; - } - -#define SSHD_MAXSTARTUPS_LOG_INTERVAL (5 * 60) - if (last_drop == 0) { - error("beginning MaxStartups throttling"); - drop_level = SYSLOG_LEVEL_INFO; - first_drop = now; - ndropped = 0; - } else if (last_drop + SSHD_MAXSTARTUPS_LOG_INTERVAL < now) { - /* Periodic logs */ - error("in MaxStartups throttling for %s, " - "%u connections dropped", - fmt_timeframe(now - first_drop), ndropped + 1); - drop_level = SYSLOG_LEVEL_INFO; + /* PerSourcePenalties */ + if (!srclimit_penalty_check_allow(sock, &subreason)) { + reason = "PerSourcePenalties"; + rl = &ratelimit_penalty; + } else { + /* MaxStartups */ + if (!should_drop_connection(startups) && + srclimit_check_allow(sock, notify_pipe) == 1) + return 0; + reason = "Maxstartups"; + rl = &ratelimit_maxstartups; } - last_drop = now; - ndropped++; - reason = "past Maxstartups"; - handle: laddr = get_local_ipaddr(sock); raddr = get_peer_ipaddr(sock); - do_log2(drop_level, "drop connection #%d from [%s]:%d on [%s]:%d %s", + ratelimited = log_ratelimit(rl, time(NULL), NULL, &ndropped); + do_log2(ratelimited ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO, + "drop connection #%d from [%s]:%d on [%s]:%d %s", startups, raddr, get_peer_port(sock), laddr, get_local_port(sock), - reason); + subreason != NULL ? subreason : reason); free(laddr); free(raddr); + if (ndropped != 0) { + logit("%s logging rate-limited: additional %u connections " + "dropped", reason, ndropped); + } + /* best-effort notification to client */ (void)write(sock, msg, sizeof(msg) - 1); return 1; @@ -708,11 +671,13 @@ usage(void) static struct sshbuf * pack_hostkeys(void) { - struct sshbuf *keybuf = NULL, *hostkeys = NULL; + struct sshbuf *m = NULL, *keybuf = NULL, *hostkeys = NULL; int r; u_int i; + size_t len; - if ((keybuf = sshbuf_new()) == NULL || + if ((m = sshbuf_new()) == NULL || + (keybuf = sshbuf_new()) == NULL || (hostkeys = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -747,19 +712,28 @@ pack_hostkeys(void) } } + if ((r = sshbuf_put_u32(m, 0)) != 0 || + (r = sshbuf_put_u8(m, 0)) != 0 || + (r = sshbuf_put_stringb(m, hostkeys)) != 0) + fatal_fr(r, "compose message"); + if ((len = sshbuf_len(m)) < 5 || len > 0xffffffff) + fatal_f("bad length %zu", len); + POKE_U32(sshbuf_mutable_ptr(m), len - 4); + sshbuf_free(keybuf); - return hostkeys; + sshbuf_free(hostkeys); + return m; } -static void -send_rexec_state(int fd, struct sshbuf *conf) +static struct sshbuf * +pack_config(struct sshbuf *conf) { - struct sshbuf *m = NULL, *inc = NULL, *hostkeys = NULL; + struct sshbuf *m = NULL, *inc = NULL; struct include_item *item = NULL; - int r, sz; + size_t len; + int r; - debug3_f("entering fd = %d config len %zu", fd, - sshbuf_len(conf)); + debug3_f("d config len %zu", sshbuf_len(conf)); if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) @@ -773,44 +747,79 @@ send_rexec_state(int fd, struct sshbuf *conf) fatal_fr(r, "compose includes"); } - hostkeys = pack_hostkeys(); - - /* - * Protocol from reexec master to child: - * string configuration - * uint64 timing_secret - * string host_keys[] { - * string private_key - * string public_key - * string certificate - * } - * string included_files[] { - * string selector - * string filename - * string contents - * } - */ - if ((r = sshbuf_put_stringb(m, conf)) != 0 || + if ((r = sshbuf_put_u32(m, 0)) != 0 || + (r = sshbuf_put_u8(m, 0)) != 0 || + (r = sshbuf_put_stringb(m, conf)) != 0 || (r = sshbuf_put_u64(m, options.timing_secret)) != 0 || - (r = sshbuf_put_stringb(m, hostkeys)) != 0 || (r = sshbuf_put_stringb(m, inc)) != 0) fatal_fr(r, "compose config"); + if ((len = sshbuf_len(m)) < 5 || len > 0xffffffff) + fatal_f("bad length %zu", len); + POKE_U32(sshbuf_mutable_ptr(m), len - 4); + + sshbuf_free(inc); + + debug3_f("done"); + return m; +} + +/* + * Protocol from reexec master to child: + * uint32 size + * uint8 type (ignored) + * string configuration + * uint64 timing_secret + * string included_files[] { + * string selector + * string filename + * string contents + * } + * Second message + * uint32 size + * uint8 type (ignored) + * string host_keys[] { + * string private_key + * string public_key + * string certificate + * } + */ +/* + * This function is used only if inet_flag or debug_flag is set, + * otherwise the data is sent from the main poll loop. + * It sends the config from a child process back to the parent. + * The parent will read the config after exec. + */ +static void +send_rexec_state(int fd) +{ + struct sshbuf *keys; + u_int mlen; + pid_t pid; #ifndef WINDOWS - /* We need to fit the entire message inside the socket send buffer */ - sz = ROUNDUP(sshbuf_len(m) + 5, 16*1024); - if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof sz) == -1) - fatal_f("setsockopt SO_SNDBUF: %s", strerror(errno)); -#endif /* WINDOWS */ + if ((pid = fork()) == -1) + fatal_f("fork failed: %s", strerror(errno)); + if (pid != 0) + return; +#endif /* !WINDOWS */ - if (ssh_msg_send(fd, 0, m) == -1) - error_f("ssh_msg_send failed"); + debug3_f("entering fd = %d config len %zu", fd, + sshbuf_len(config)); - sshbuf_free(m); - sshbuf_free(inc); - sshbuf_free(hostkeys); + mlen = sshbuf_len(config); + if (atomicio(vwrite, fd, sshbuf_mutable_ptr(config), mlen) != mlen) + error_f("write: %s", strerror(errno)); + keys = pack_hostkeys(); + mlen = sshbuf_len(keys); + if (atomicio(vwrite, fd, sshbuf_mutable_ptr(keys), mlen) != mlen) + error_f("write: %s", strerror(errno)); + + sshbuf_free(keys); debug3_f("done"); +#ifndef WINDOWS + exit(0); +#endif /* !WINDOWS */ } /* @@ -925,12 +934,15 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, int log_stderr) { struct pollfd *pfd = NULL; - int i, ret, npfd; + int i, ret, npfd, r; int oactive = -1, listening = 0, lameduck = 0; - int startup_p[2] = { -1 , -1 }, *startup_pollfd; + int *startup_pollfd; + ssize_t len; + const u_char *ptr; char c = 0; struct sockaddr_storage from; struct early_child *child; + struct sshbuf *buf; socklen_t fromlen; u_char rnd[256]; sigset_t nsigset, osigset; @@ -1008,6 +1020,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, if (children[i].pipefd != -1) { pfd[npfd].fd = children[i].pipefd; pfd[npfd].events = POLLIN; + if (children[i].config != NULL || + children[i].keys != NULL) + pfd[npfd].events |= POLLOUT; startup_pollfd[i] = npfd++; } } @@ -1023,6 +1038,50 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, if (ret == -1) continue; + for (i = 0; i < options.max_startups; i++) { + if (children[i].pipefd == -1 || + startup_pollfd[i] == -1 || + !(pfd[startup_pollfd[i]].revents & POLLOUT)) + continue; + if (children[i].config) + buf = children[i].config; + else if (children[i].keys) + buf = children[i].keys; + else { + error_f("no buffer to send"); + continue; + } + ptr = sshbuf_ptr(buf); + len = sshbuf_len(buf); + ret = write(children[i].pipefd, ptr, len); + if (ret == -1 && (errno == EINTR || errno == EAGAIN)) + continue; + if (ret <= 0) { + if (children[i].early) + listening--; + srclimit_done(children[i].pipefd); + child_close(&(children[i]), 0, 0); + continue; + } + if (ret == len) { + /* finished sending buffer */ + sshbuf_free(buf); + if (children[i].config == buf) { + /* sent config, now send keys */ + children[i].config = NULL; + children[i].keys = pack_hostkeys(); + } else if (children[i].keys == buf) { + /* sent both config and keys */ + children[i].keys = NULL; + } else { + fatal("config buf not set"); + } + + } else { + if ((r = sshbuf_consume(buf, ret)) != 0) + fatal_fr(r, "config buf inconsistent"); + } + } for (i = 0; i < options.max_startups; i++) { if (children[i].pipefd == -1 || startup_pollfd[i] == -1 || @@ -1046,6 +1105,17 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, child_close(&(children[i]), 0, 0); break; case 1: + if (children[i].config) { + error_f("startup pipe %d (fd=%d)" + " early read", i, children[i].pipefd); + if (children[i].early) + listening--; + if (children[i].pid > 0) + kill(children[i].pid, SIGTERM); + srclimit_done(children[i].pipefd); + child_close(&(children[i]), 0, 0); + break; + } if (children[i].early && c == '\0') { /* child has finished preliminaries */ listening--; @@ -1087,26 +1157,18 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, close(*newsock); continue; } - if (pipe(startup_p) == -1) { - error_f("pipe(startup_p): %s", strerror(errno)); - close(*newsock); - continue; - } - if (drop_connection(*newsock, - children_active, startup_p[0])) { - close(*newsock); - close(startup_p[0]); - close(startup_p[1]); - continue; - } - if (socketpair(AF_UNIX, SOCK_STREAM, 0, config_s) == -1) { error("reexec socketpair: %s", strerror(errno)); close(*newsock); - close(startup_p[0]); - close(startup_p[1]); + continue; + } + if (drop_connection(*newsock, + children_active, config_s[0])) { + close(*newsock); + close(config_s[0]); + close(config_s[1]); continue; } @@ -1125,17 +1187,10 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, close_listen_socks(); *sock_in = *newsock; *sock_out = *newsock; - close(startup_p[0]); #ifndef WINDOWS - close(startup_p[1]); -#endif /* WINDOWS */ - startup_pipe = -1; -#ifdef WINDOWS - debug_startup_p = startup_p[1]; -#else - send_rexec_state(config_s[0], cfg); + send_rexec_state(config_s[0]); close(config_s[0]); -#endif /* WINDOWS */ +#endif /* !WINDOWS */ free(pfd); return; } @@ -1147,14 +1202,13 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, if (posix_spawn_file_actions_init(&actions) != 0 || posix_spawn_file_actions_adddup2(&actions, *newsock, STDIN_FILENO) != 0 || posix_spawn_file_actions_adddup2(&actions, *newsock, STDOUT_FILENO) != 0 || - posix_spawn_file_actions_adddup2(&actions, startup_p[1], REEXEC_STARTUP_PIPE_FD) != 0 || posix_spawn_file_actions_adddup2(&actions, config_s[1], REEXEC_CONFIG_PASS_FD) != 0 || posix_spawnattr_init(&attributes) != 0 || posix_spawnattr_setflags(&attributes, POSIX_SPAWN_SETPGROUP) != 0 || posix_spawnattr_setpgroup(&attributes, 0) != 0) error("posix_spawn initialization failed"); else { - child = child_register(startup_p[0], *newsock); + child = child_register(config_s[0], *newsock); if (posix_spawn(&child->pid, rexec_argv[0], &actions, &attributes, rexec_argv, NULL) != 0) error("%s, posix_spawn failed", __func__); posix_spawn_file_actions_destroy(&actions); @@ -1168,8 +1222,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, * parent continues listening. */ platform_pre_fork(); + set_nonblock(config_s[0]); listening++; - child = child_register(startup_p[0], *newsock); + child = child_register(config_s[0], *newsock); if ((child->pid = fork()) == 0) { /* * Child. Close the listening and @@ -1180,7 +1235,6 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, * the connection. */ platform_post_fork_child(); - startup_pipe = startup_p[1]; close_startup_pipes(); close_listen_socks(); *sock_in = *newsock; @@ -1202,10 +1256,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, debug("Forked child %ld.", (long)child->pid); #endif /* fork unsupported */ - close(startup_p[1]); close(config_s[1]); - send_rexec_state(config_s[0], cfg); - close(config_s[0]); close(*newsock); /* @@ -1297,9 +1348,9 @@ main(int ac, char **av) int need_chroot = 1; #ifdef WINDOWS // rexec_argv is still defined globally for use in server_accept_loop - char* fp, * line, * logfile = NULL; + char *args, *fp, *line, *logfile = NULL; #else /* WINDOWS */ - char* fp, * line, * logfile = NULL, **rexec_argv = NULL; + char *args, *fp, *line, *logfile = NULL, **rexec_argv = NULL; #endif /* WINDOWS */ struct stat sb; u_int i, j; @@ -1307,6 +1358,9 @@ main(int ac, char **av) struct sshkey *key; struct sshkey *pubkey; struct connection_info connection_info; +#ifndef WINDOWS + struct utsname utsname +#endif /* !WINDOWS */ sigset_t sigmask; memset(&connection_info, 0, sizeof(connection_info)); @@ -1342,6 +1396,7 @@ main(int ac, char **av) initialize_server_options(&options); /* Parse command-line arguments. */ + args = argv_assemble(ac, av); /* logged later */ while ((opt = getopt(ac, av, "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) { switch (opt) { @@ -1455,7 +1510,7 @@ main(int ac, char **av) break; } } - if (!test_flag && !do_dump_cfg && !path_absolute(av[0])) + if (!test_flag && !inetd_flag && !do_dump_cfg && !path_absolute(av[0])) fatal("sshd requires execution with an absolute path"); closefrom(STDERR_FILENO + 1); @@ -1511,6 +1566,18 @@ main(int ac, char **av) fatal("Config test connection parameter (-C) provided without " "test mode (-T)"); + debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); +#ifndef WINDOWS + if (uname(&utsname) != 0) { + memset(&utsname, 0, sizeof(utsname)); + strlcpy(utsname.sysname, "UNKNOWN", sizeof(utsname.sysname)); + } + debug3("Running on %s %s %s %s", utsname.sysname, utsname.release, + utsname.version, utsname.machine); +#endif /* WINDOWS */ + debug3("Started with: %s", args); + free(args); + /* Fetch our configuration */ if ((cfg = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); @@ -1558,8 +1625,6 @@ main(int ac, char **av) exit(1); } - debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); - if (do_dump_cfg) print_config(&connection_info); @@ -1771,6 +1836,13 @@ main(int ac, char **av) fatal("%s does not exist or is not executable", rexec_argv[0]); debug3("using %s for re-exec", rexec_argv[0]); + /* Ensure that the privsep binary exists now too. */ + if (stat(options.sshd_auth_path, &sb) != 0 || + !(sb.st_mode & (S_IXOTH|S_IXUSR))) { + fatal("%s does not exist or is not executable", + options.sshd_auth_path); + } + listener_proctitle = prepare_proctitle(ac, av); /* Ensure that umask disallows at least group and world write */ @@ -1811,13 +1883,15 @@ main(int ac, char **av) /* ignore SIGPIPE */ ssh_signal(SIGPIPE, SIG_IGN); + config = pack_config(cfg); + /* Get a connection, either from inetd or a listening TCP socket */ if (inetd_flag) { /* Send configuration to ancestor sshd-session process */ if (socketpair(AF_UNIX, SOCK_STREAM, 0, config_s) == -1) fatal("socketpair: %s", strerror(errno)); #ifndef WINDOWS - send_rexec_state(config_s[0], cfg); + send_rexec_state(config_s[0]); close(config_s[0]); #endif /* WINDOWS */ } else { @@ -1867,8 +1941,8 @@ main(int ac, char **av) error("setsid: %.100s", strerror(errno)); #ifndef FORK_NOT_SUPPORTED - debug("rexec start in %d out %d newsock %d pipe %d sock %d/%d", - sock_in, sock_out, newsock, startup_pipe, config_s[0], config_s[1]); + debug("rexec start in %d out %d newsock %d config_s %d/%d", + sock_in, sock_out, newsock, config_s[0], config_s[1]); if (!inetd_flag) { if (dup2(newsock, STDIN_FILENO) == -1) fatal("dup2 stdin: %s", strerror(errno)); @@ -1882,13 +1956,6 @@ main(int ac, char **av) fatal("dup2 config_s: %s", strerror(errno)); close(config_s[1]); } - if (startup_pipe == -1) - close(REEXEC_STARTUP_PIPE_FD); - else if (startup_pipe != REEXEC_STARTUP_PIPE_FD) { - if (dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD) == -1) - fatal("dup2 startup_p: %s", strerror(errno)); - close(startup_pipe); - } log_redirect_stderr_to(NULL); closefrom(REEXEC_MIN_FREE_FD); @@ -1899,28 +1966,32 @@ main(int ac, char **av) #else posix_spawn_file_actions_t actions; posix_spawnattr_t attributes; + pid_t pid; if (posix_spawn_file_actions_init(&actions) != 0 || (debug_flag && posix_spawn_file_actions_adddup2(&actions, newsock, STDIN_FILENO) != 0) || (debug_flag && posix_spawn_file_actions_adddup2(&actions, newsock, STDOUT_FILENO) != 0) || - (debug_flag && posix_spawn_file_actions_adddup2(&actions, debug_startup_p, REEXEC_STARTUP_PIPE_FD) != 0) || posix_spawn_file_actions_adddup2(&actions, config_s[1], REEXEC_CONFIG_PASS_FD) != 0 || posix_spawnattr_init(&attributes) != 0 || posix_spawnattr_setflags(&attributes, POSIX_SPAWN_SETPGROUP) != 0 || posix_spawnattr_setpgroup(&attributes, 0) != 0) error("posix_spawn initialization failed"); else { - pid_t pid; if (posix_spawn(&pid, rexec_argv[0], &actions, &attributes, rexec_argv, NULL) != 0) error("%s, posix_spawn failed", __func__); posix_spawn_file_actions_destroy(&actions); posix_spawnattr_destroy(&attributes); } - close(debug_startup_p); close(config_s[1]); - send_rexec_state(config_s[0], cfg); + send_rexec_state(config_s[0]); close(config_s[0]); close(newsock); - cleanup_exit(255); + // wait for child to exit to propagate exit code to terminal + int status; + if (waitpid(pid, &status, 0) == -1) { + error("waitpid failed"); + cleanup_exit(255); + } + cleanup_exit(status); #endif /* FORK_NOT_SUPPORTED */ } diff --git a/sshd_config b/sshd_config index 36894ace503..0f4a3a7247a 100644 --- a/sshd_config +++ b/sshd_config @@ -1,4 +1,4 @@ -# $OpenBSD: sshd_config,v 1.104 2021/07/02 05:11:21 dtucker Exp $ +# $OpenBSD: sshd_config,v 1.105 2024/12/03 14:12:47 dtucker Exp $ # This is the sshd server system-wide configuration file. See # sshd_config(5) for more information. @@ -53,11 +53,13 @@ AuthorizedKeysFile .ssh/authorized_keys # Don't read the user's ~/.rhosts and ~/.shosts files #IgnoreRhosts yes -# To disable tunneled clear text passwords, change to no here! +# To disable tunneled clear text passwords, change to "no" here! #PasswordAuthentication yes #PermitEmptyPasswords no -# Change to no to disable s/key passwords +# Change to "no" to disable keyboard-interactive authentication. Depending on +# the system's configuration, this may involve passwords, challenge-response, +# one-time passwords or some combination of these and other methods. #KbdInteractiveAuthentication yes # Kerberos options diff --git a/sshd_config.0 b/sshd_config.0 index 6883dda4b19..2f77b4f4c0b 100644 --- a/sshd_config.0 +++ b/sshd_config.0 @@ -150,12 +150,13 @@ DESCRIPTION Specifies the file that contains the public keys used for user authentication. The format is described in the AUTHORIZED_KEYS FILE FORMAT section of sshd(8). Arguments to AuthorizedKeysFile - accept the tokens described in the TOKENS section. After - expansion, AuthorizedKeysFile is taken to be an absolute path or - one relative to the user's home directory. Multiple files may be - listed, separated by whitespace. Alternately this option may be - set to none to skip checking for user keys in files. The default - is ".ssh/authorized_keys .ssh/authorized_keys2". + may include wildcards and accept the tokens described in the + TOKENS section. After expansion, AuthorizedKeysFile is taken to + be an absolute path or one relative to the user's home directory. + Multiple files may be listed, separated by whitespace. + Alternately this option may be set to none to skip checking for + user keys in files. The default is ".ssh/authorized_keys + .ssh/authorized_keys2". AuthorizedPrincipalsCommand Specifies a program to be used to generate the list of allowed @@ -190,12 +191,13 @@ DESCRIPTION options (as described in AUTHORIZED_KEYS FILE FORMAT in sshd(8)). Empty lines and comments starting with M-bM-^@M-^X#M-bM-^@M-^Y are ignored. - Arguments to AuthorizedPrincipalsFile accept the tokens described - in the TOKENS section. After expansion, AuthorizedPrincipalsFile - is taken to be an absolute path or one relative to the user's - home directory. The default is none, i.e. not to use a - principals file M-bM-^@M-^S in this case, the username of the user must - appear in a certificate's principals list for it to be accepted. + Arguments to AuthorizedPrincipalsFile may include wildcards and + accept the tokens described in the TOKENS section. After + expansion, AuthorizedPrincipalsFile is taken to be an absolute + path or one relative to the user's home directory. The default + is none, i.e. not to use a principals file M-bM-^@M-^S in this case, the + username of the user must appear in a certificate's principals + list for it to be accepted. Note that AuthorizedPrincipalsFile is only used when authentication proceeds using a CA listed in TrustedUserCAKeys @@ -336,8 +338,8 @@ DESCRIPTION The default is: chacha20-poly1305@openssh.com, - aes128-ctr,aes192-ctr,aes256-ctr, - aes128-gcm@openssh.com,aes256-gcm@openssh.com + aes128-gcm@openssh.com,aes256-gcm@openssh.com, + aes128-ctr,aes192-ctr,aes256-ctr The list of available ciphers may also be obtained using "ssh -Q cipher". @@ -644,16 +646,16 @@ DESCRIPTION ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 + mlkem768x25519-sha256 + sntrup761x25519-sha512 sntrup761x25519-sha512@openssh.com The default is: - sntrup761x25519-sha512@openssh.com, + mlkem768x25519-sha256, + sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, curve25519-sha256,curve25519-sha256@libssh.org, - ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, - diffie-hellman-group-exchange-sha256, - diffie-hellman-group16-sha512,diffie-hellman-group18-sha512, - diffie-hellman-group14-sha256 + ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521 The list of supported key exchange algorithms may also be obtained using "ssh -Q KexAlgorithms". @@ -690,9 +692,9 @@ DESCRIPTION LogVerbose Specify one or more overrides to LogLevel. An override consists - of a pattern lists that matches the source file, function and - line number to force detailed logging for. For example, an - override pattern of: + of one or more pattern lists that matches the source file, + function and line number to force detailed logging for. For + example, an override pattern of: kex.c:*:1000,*:kex_exchange_identification():*,packet.c:* @@ -753,8 +755,10 @@ DESCRIPTION the first instance of the keyword is applied. The arguments to Match are one or more criteria-pattern pairs or - the single token All which matches all criteria. The available - criteria are User, Group, Host, LocalAddress, LocalPort, RDomain, + one of the single token criteria: All, which matches all + criteria, or Invalid-User, which matches when the requested user- + name does not match any known account. The available criteria + are User, Group, Host, LocalAddress, LocalPort, Version, RDomain, and Address (with RDomain representing the rdomain(4) on which the connection was received). @@ -770,6 +774,9 @@ DESCRIPTION with bits set in this host portion of the address. For example, 192.0.2.0/33 and 192.0.2.0/8, respectively. + The Version keyword matches against the version string of + sshd(8), for example M-bM-^@M-^\OpenSSH_10.0M-bM-^@M-^]. + Only a subset of keywords may be used on the lines following a Match keyword. Available keywords are AcceptEnv, AllowAgentForwarding, AllowGroups, AllowStreamLocalForwarding, @@ -787,10 +794,11 @@ DESCRIPTION PAMServiceName, PasswordAuthentication, PermitEmptyPasswords, PermitListen, PermitOpen, PermitRootLogin, PermitTTY, PermitTunnel, PermitUserRC, PubkeyAcceptedAlgorithms, - PubkeyAuthentication, PubkeyAuthOptions, RekeyLimit, RevokedKeys, - RDomain, SetEnv, StreamLocalBindMask, StreamLocalBindUnlink, - TrustedUserCAKeys, UnusedConnectionTimeout, X11DisplayOffset, - X11Forwarding and X11UseLocalhost. + PubkeyAuthentication, PubkeyAuthOptions, RefuseConnection, + RekeyLimit, RevokedKeys, RDomain, SetEnv, StreamLocalBindMask, + StreamLocalBindUnlink, TrustedUserCAKeys, + UnusedConnectionTimeout, X11DisplayOffset, X11Forwarding and + X11UseLocalhost. MaxAuthTries Specifies the maximum number of authentication attempts permitted @@ -833,7 +841,7 @@ DESCRIPTION PasswordAuthentication Specifies whether password authentication is allowed. The - default is sshd. + default is yes. PermitEmptyPasswords When password authentication is allowed, it specifies whether the @@ -950,8 +958,8 @@ DESCRIPTION accumulated. Penalties are enabled by default with the default settings listed - below but may disabled using the off keyword. The defaults may - be overridden by specifying one or more of the keywords below, + below but may disabled using the no keyword. The defaults may be + overridden by specifying one or more of the keywords below, separated by whitespace. All keywords accept arguments, e.g. "crash:2m". @@ -964,6 +972,11 @@ DESCRIPTION after making one or more unsuccessful authentication attempts (default: 5s). + refuseconnection:duration + Specifies how long to refuse clients that were + administratively prohibited connection via the + RefuseConnection option (default: 10s). + noauth:duration Specifies how long to refuse clients that disconnect without attempting authentication (default: 1s). This @@ -973,7 +986,7 @@ DESCRIPTION grace-exceeded:duration Specifies how long to refuse clients that fail to - authenticate after LoginGraceTime (default: 20s). + authenticate after LoginGraceTime (default: 10s). max:duration Specifies the maximum time a particular source address @@ -1089,6 +1102,13 @@ DESCRIPTION Specifies whether public key authentication is allowed. The default is yes. + RefuseConnection + Indicates that sshd(8) should unconditionally terminate the + connection. Additionally, a refuseconnection penalty may be + recorded against the source of the connection if + PerSourcePenalties are enabled. This option is only really + useful in a Match block. + RekeyLimit Specifies the maximum amount of data that may be transmitted or received before the session key is renegotiated, optionally @@ -1138,6 +1158,12 @@ DESCRIPTION environment and any variables specified by the user via AcceptEnv or PermitUserEnvironment. + SshdAuthPath + Overrides the default path to the sshd-auth binary that is + invoked to complete user authentication. The default is + /usr/libexec/sshd-auth. This option is intended for use by + tests. + SshdSessionPath Overrides the default path to the sshd-session binary that is invoked to handle each connection. The default is @@ -1390,4 +1416,4 @@ AUTHORS versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -OpenBSD 7.5 June 24, 2024 OpenBSD 7.5 +OpenBSD 7.6 February 15, 2025 OpenBSD 7.6 diff --git a/sshd_config.5 b/sshd_config.5 index ce872de5290..c07717375d9 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.365 2024/06/24 06:59:39 jmc Exp $ -.Dd $Mdocdate: June 24 2024 $ +.\" $OpenBSD: sshd_config.5,v 1.381 2025/02/15 01:52:07 djm Exp $ +.Dd $Mdocdate: February 15 2025 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -250,7 +250,7 @@ If no arguments are specified then the username of the target user is used. .Pp The program should produce on standard output zero or more lines of authorized_keys output (see -.Sx AUTHORIZED_KEYS +.Cm AUTHORIZED_KEYS in .Xr sshd 8 ) . .Cm AuthorizedKeysCommand @@ -279,7 +279,7 @@ The format is described in the AUTHORIZED_KEYS FILE FORMAT section of .Xr sshd 8 . Arguments to .Cm AuthorizedKeysFile -accept the tokens described in the +may include wildcards and accept the tokens described in the .Sx TOKENS section. After expansion, @@ -339,7 +339,7 @@ When using certificates signed by a key listed in this file lists names, one of which must appear in the certificate for it to be accepted for authentication. Names are listed one per line preceded by key options (as described in -.Sx AUTHORIZED_KEYS FILE FORMAT +.Cm AUTHORIZED_KEYS FILE FORMAT in .Xr sshd 8 ) . Empty lines and comments starting with @@ -348,7 +348,7 @@ are ignored. .Pp Arguments to .Cm AuthorizedPrincipalsFile -accept the tokens described in the +may include wildcards and accept the tokens described in the .Sx TOKENS section. After expansion, @@ -576,8 +576,8 @@ chacha20-poly1305@openssh.com The default is: .Bd -literal -offset indent chacha20-poly1305@openssh.com, -aes128-ctr,aes192-ctr,aes256-ctr, -aes128-gcm@openssh.com,aes256-gcm@openssh.com +aes128-gcm@openssh.com,aes256-gcm@openssh.com, +aes128-ctr,aes192-ctr,aes256-ctr .Ed .Pp The list of available ciphers may also be obtained using @@ -1050,17 +1050,19 @@ ecdh-sha2-nistp384 .It ecdh-sha2-nistp521 .It +mlkem768x25519-sha256 +.It +sntrup761x25519-sha512 +.It sntrup761x25519-sha512@openssh.com .El .Pp The default is: .Bd -literal -offset indent -sntrup761x25519-sha512@openssh.com, +mlkem768x25519-sha256, +sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com, curve25519-sha256,curve25519-sha256@libssh.org, -ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521, -diffie-hellman-group-exchange-sha256, -diffie-hellman-group16-sha512,diffie-hellman-group18-sha512, -diffie-hellman-group14-sha256 +ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521 .Ed .Pp The list of supported key exchange algorithms may also be obtained using @@ -1133,8 +1135,8 @@ Logging with a DEBUG level violates the privacy of users and is not recommended. .It Cm LogVerbose Specify one or more overrides to .Cm LogLevel . -An override consists of a pattern lists that matches the source file, function -and line number to force detailed logging for. +An override consists of one or more pattern lists that matches the +source file, function and line number to force detailed logging for. For example, an override pattern of: .Bd -literal -offset indent kex.c:*:1000,*:kex_exchange_identification():*,packet.c:* @@ -1232,15 +1234,18 @@ applied. .Pp The arguments to .Cm Match -are one or more criteria-pattern pairs or the single token -.Cm All -which matches all criteria. +are one or more criteria-pattern pairs or one of the single token criteria: +.Cm All , +which matches all criteria, or +.Cm Invalid-User , +which matches when the requested user-name does not match any known account. The available criteria are .Cm User , .Cm Group , .Cm Host , .Cm LocalAddress , .Cm LocalPort , +.Cm Version , .Cm RDomain , and .Cm Address @@ -1266,6 +1271,13 @@ it is an error to specify a mask length that is too long for the address or one with bits set in this host portion of the address. For example, 192.0.2.0/33 and 192.0.2.0/8, respectively. .Pp +The +.Cm Version +keyword matches against the version string of +.Xr sshd 8 , +for example +.Dq OpenSSH_10.0 . +.Pp Only a subset of keywords may be used on the lines following a .Cm Match keyword. @@ -1319,6 +1331,7 @@ Available keywords are .Cm PubkeyAcceptedAlgorithms , .Cm PubkeyAuthentication , .Cm PubkeyAuthOptions , +.Cm RefuseConnection , .Cm RekeyLimit , .Cm RevokedKeys , .Cm RDomain , @@ -1384,7 +1397,7 @@ The default is .It Cm PasswordAuthentication Specifies whether password authentication is allowed. The default is -.Cm sshd . +.Cm yes . .It Cm PermitEmptyPasswords When password authentication is allowed, it specifies whether the server allows login to accounts with empty password strings. @@ -1599,6 +1612,11 @@ Specifies how long to refuse clients that cause a crash of .It Cm authfail:duration Specifies how long to refuse clients that disconnect after making one or more unsuccessful authentication attempts (default: 5s). +.It Cm refuseconnection:duration +Specifies how long to refuse clients that were administratively prohibited +connection via the +.Cm RefuseConnection +option (default: 10s). .It Cm noauth:duration Specifies how long to refuse clients that disconnect without attempting authentication (default: 1s). @@ -1608,7 +1626,7 @@ scanning tools such as .It Cm grace-exceeded:duration Specifies how long to refuse clients that fail to authenticate after .Cm LoginGraceTime -(default: 20s). +(default: 10s). .It Cm max:duration Specifies the maximum time a particular source address range will be refused access for (default: 10m). @@ -1756,6 +1774,18 @@ options have any effect for other, non-FIDO, public key types. Specifies whether public key authentication is allowed. The default is .Cm yes . +.It Cm RefuseConnection +Indicates that +.Xr sshd 8 +should unconditionally terminate the connection. +Additionally, a +.Cm refuseconnection +penalty may be recorded against the source of the connection if +.Cm PerSourcePenalties +are enabled. +This option is only really useful in a +.Cm Match +block. .It Cm RekeyLimit Specifies the maximum amount of data that may be transmitted or received before the session key is renegotiated, optionally followed by a maximum @@ -1831,6 +1861,13 @@ via .Cm AcceptEnv or .Cm PermitUserEnvironment . +.It Cm SshdAuthPath +Overrides the default path to the +.Cm sshd-auth +binary that is invoked to complete user authentication. +The default is +.Pa /usr/libexec/sshd-auth . +This option is intended for use by tests. .It Cm SshdSessionPath Overrides the default path to the .Cm sshd-session diff --git a/sshkey.c b/sshkey.c index 5ac284cf0d5..a33fc072487 100644 --- a/sshkey.c +++ b/sshkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.142 2024/01/11 01:45:36 djm Exp $ */ +/* $OpenBSD: sshkey.c,v 1.148 2024/12/03 15:53:51 tb Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -28,6 +28,9 @@ #include "includes.h" #include +#ifndef WINDOWS +#include +#endif #include #ifdef WITH_OPENSSL @@ -66,6 +69,7 @@ #endif #ifdef WINDOWS #include +#include #endif #include "openbsd-compat/openssl-compat.h" @@ -87,9 +91,6 @@ #define DEFAULT_CIPHERNAME "aes256-ctr" #define DEFAULT_ROUNDS 24 -/* Version identification string for SSH v1 identity files. */ -#define LEGACY_BEGIN "SSH PRIVATE KEY FILE FORMAT 1.1\n" - /* * Constants relating to "shielding" support; protection of keys expected * to remain in memory for long durations @@ -257,22 +258,36 @@ sshkey_ssh_name_plain(const struct sshkey *k) k->ecdsa_nid); } -int -sshkey_type_from_name(const char *name) +static int +type_from_name(const char *name, int allow_short) { int i; const struct sshkey_impl *impl; for (i = 0; keyimpls[i] != NULL; i++) { impl = keyimpls[i]; + if (impl->name != NULL && strcmp(name, impl->name) == 0) + return impl->type; /* Only allow shortname matches for plain key types */ - if ((impl->name != NULL && strcmp(name, impl->name) == 0) || - (!impl->cert && strcasecmp(impl->shortname, name) == 0)) + if (allow_short && !impl->cert && impl->shortname != NULL && + strcasecmp(impl->shortname, name) == 0) return impl->type; } return KEY_UNSPEC; } +int +sshkey_type_from_name(const char *name) +{ + return type_from_name(name, 0); +} + +int +sshkey_type_from_shortname(const char *name) +{ + return type_from_name(name, 1); +} + static int key_type_is_ecdsa_variant(int type) { @@ -490,6 +505,98 @@ sshkey_type_certified(int type) } #ifdef WITH_OPENSSL +static const EVP_MD * +ssh_digest_to_md(int hash_alg) +{ + switch (hash_alg) { + case SSH_DIGEST_SHA1: + return EVP_sha1(); + case SSH_DIGEST_SHA256: + return EVP_sha256(); + case SSH_DIGEST_SHA384: + return EVP_sha384(); + case SSH_DIGEST_SHA512: + return EVP_sha512(); + } + return NULL; +} + +int +sshkey_pkey_digest_sign(EVP_PKEY *pkey, int hash_alg, u_char **sigp, + size_t *lenp, const u_char *data, size_t datalen) +{ + EVP_MD_CTX *ctx = NULL; + u_char *sig = NULL; + int ret; + size_t slen; + const EVP_MD *evpmd; + + *sigp = NULL; + *lenp = 0; + + slen = EVP_PKEY_size(pkey); + if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM || + (evpmd = ssh_digest_to_md(hash_alg)) == NULL) + return SSH_ERR_INVALID_ARGUMENT; + + if ((sig = malloc(slen)) == NULL) + return SSH_ERR_ALLOC_FAIL; + + if ((ctx = EVP_MD_CTX_new()) == NULL) { + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (EVP_DigestSignInit(ctx, NULL, evpmd, NULL, pkey) != 1 || + EVP_DigestSign(ctx, sig, &slen, data, datalen) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + + *sigp = sig; + *lenp = slen; + /* Now owned by the caller */ + sig = NULL; + ret = 0; + + out: + EVP_MD_CTX_free(ctx); + free(sig); + return ret; +} + +int +sshkey_pkey_digest_verify(EVP_PKEY *pkey, int hash_alg, const u_char *data, + size_t datalen, u_char *sigbuf, size_t siglen) +{ + EVP_MD_CTX *ctx = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; + const EVP_MD *evpmd; + + if ((evpmd = ssh_digest_to_md(hash_alg)) == NULL) + return SSH_ERR_INVALID_ARGUMENT; + if ((ctx = EVP_MD_CTX_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if (EVP_DigestVerifyInit(ctx, NULL, evpmd, NULL, pkey) != 1) { + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + switch (EVP_DigestVerify(ctx, sigbuf, siglen, data, datalen)) { + case 1: + ret = 0; + break; + case 0: + ret = SSH_ERR_SIGNATURE_INVALID; + break; + default: + ret = SSH_ERR_LIBCRYPTO_ERROR; + break; + } + + out: + EVP_MD_CTX_free(ctx); + return ret; +} + /* XXX: these are really begging for a table-driven approach */ int sshkey_curve_name_to_nid(const char *name) @@ -656,6 +763,52 @@ sshkey_sk_cleanup(struct sshkey *k) k->sk_key_handle = k->sk_reserved = NULL; } +#if defined(MAP_CONCEAL) +# define PREKEY_MMAP_FLAG MAP_CONCEAL +#elif defined(MAP_NOCORE) +# define PREKEY_MMAP_FLAG MAP_NOCORE +#else +# define PREKEY_MMAP_FLAG 0 +#endif + +static int +sshkey_prekey_alloc(u_char **prekeyp, size_t len) +{ + u_char *prekey; + + *prekeyp = NULL; +#ifdef WINDOWS + prekey = VirtualAlloc(NULL, len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + if (prekey == NULL) { + return SSH_ERR_SYSTEM_ERROR; + } + VirtualLock(prekey, len); +#else + if ((prekey = mmap(NULL, len, PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE|PREKEY_MMAP_FLAG, -1, 0)) == MAP_FAILED) + return SSH_ERR_SYSTEM_ERROR; +#if defined(MADV_DONTDUMP) && !defined(MAP_CONCEAL) && !defined(MAP_NOCORE) + (void)madvise(prekey, len, MADV_DONTDUMP); +#endif +#endif /* WINDOWS */ + *prekeyp = prekey; + return 0; +} + +static void +sshkey_prekey_free(void *prekey, size_t len) +{ + if (prekey == NULL) + return; +#ifdef WINDOWS + SecureZeroMemory(prekey, len); + VirtualUnlock(prekey, len); + VirtualFree(prekey, 0, MEM_RELEASE); +#else + munmap(prekey, len); +#endif /* WINDOWS */ +} + static void sshkey_free_contents(struct sshkey *k) { @@ -669,7 +822,7 @@ sshkey_free_contents(struct sshkey *k) if (sshkey_is_cert(k)) cert_free(k->cert); freezero(k->shielded_private, k->shielded_len); - freezero(k->shield_prekey, k->shield_prekey_len); + sshkey_prekey_free(k->shield_prekey, k->shield_prekey_len); } void @@ -1340,14 +1493,12 @@ int sshkey_check_rsa_length(const struct sshkey *k, int min_size) { #ifdef WITH_OPENSSL - const BIGNUM *rsa_n; int nbits; - if (k == NULL || k->rsa == NULL || + if (k == NULL || k->pkey == NULL || (k->type != KEY_RSA && k->type != KEY_RSA_CERT)) return 0; - RSA_get0_key(k->rsa, &rsa_n, NULL, NULL); - nbits = BN_num_bits(rsa_n); + nbits = EVP_PKEY_bits(k->pkey); if (nbits < SSH_RSA_MINIMUM_MODULUS_SIZE || (min_size > 0 && nbits < min_size)) return SSH_ERR_KEY_LENGTH; @@ -1355,53 +1506,26 @@ sshkey_check_rsa_length(const struct sshkey *k, int min_size) return 0; } -#ifdef WITH_OPENSSL -# ifdef OPENSSL_HAS_ECC +#if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) int -sshkey_ecdsa_key_to_nid(EC_KEY *k) +sshkey_ecdsa_key_to_nid(const EC_KEY *k) { - EC_GROUP *eg = NULL; - int nids[] = { - NID_X9_62_prime256v1, - NID_secp384r1, -# ifdef OPENSSL_HAS_NISTP521 - NID_secp521r1, -# endif /* OPENSSL_HAS_NISTP521 */ - -1 - }; + const EC_GROUP *g; int nid; - u_int i; - const EC_GROUP *g = EC_KEY_get0_group(k); - /* - * The group may be stored in a ASN.1 encoded private key in one of two - * ways: as a "named group", which is reconstituted by ASN.1 object ID - * or explicit group parameters encoded into the key blob. Only the - * "named group" case sets the group NID for us, but we can figure - * it out for the other case by comparing against all the groups that - * are supported. - */ - if ((nid = EC_GROUP_get_curve_name(g)) > 0) - return nid; - for (i = 0; nids[i] != -1; i++) { - if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) - return -1; - if (EC_GROUP_cmp(g, eg, NULL) == 0) - break; - EC_GROUP_free(eg); - } - if (nids[i] != -1) { - /* Use the group with the NID attached */ - EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); - if (EC_KEY_set_group(k, eg) != 1) { - EC_GROUP_free(eg); - return -1; - } - } - return nids[i]; + if (k == NULL || (g = EC_KEY_get0_group(k)) == NULL) + return -1; + if ((nid = EC_GROUP_get_curve_name(g)) <= 0) + return -1; + return nid; } -# endif /* OPENSSL_HAS_ECC */ -#endif /* WITH_OPENSSL */ + +int +sshkey_ecdsa_pkey_to_nid(EVP_PKEY *pkey) +{ + return sshkey_ecdsa_key_to_nid(EVP_PKEY_get0_EC_KEY(pkey)); +} +#endif /* defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC) */ int sshkey_generate(int type, u_int bits, struct sshkey **keyp) @@ -1566,10 +1690,8 @@ sshkey_shield_private(struct sshkey *k) } /* Prepare a random pre-key, and from it an ephemeral key */ - if ((prekey = malloc(SSHKEY_SHIELD_PREKEY_LEN)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; + if ((r = sshkey_prekey_alloc(&prekey, SSHKEY_SHIELD_PREKEY_LEN)) != 0) goto out; - } arc4random_buf(prekey, SSHKEY_SHIELD_PREKEY_LEN); if ((r = ssh_digest_memory(SSHKEY_SHIELD_PREKEY_HASH, prekey, SSHKEY_SHIELD_PREKEY_LEN, @@ -1647,7 +1769,7 @@ sshkey_shield_private(struct sshkey *k) explicit_bzero(keyiv, sizeof(keyiv)); explicit_bzero(&tmp, sizeof(tmp)); freezero(enc, enclen); - freezero(prekey, SSHKEY_SHIELD_PREKEY_LEN); + sshkey_prekey_free(prekey, SSHKEY_SHIELD_PREKEY_LEN); sshkey_free(kswap); sshbuf_free(prvbuf); return r; @@ -2638,14 +2760,6 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) * EC_POINT_oct2point then the caller will need to explicitly check. */ - /* - * We shouldn't ever hit this case because bignum_get_ecpoint() - * refuses to load GF2m points. - */ - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != - NID_X9_62_prime_field) - goto out; - /* Q != infinity */ if (EC_POINT_is_at_infinity(group, public)) goto out; @@ -2745,11 +2859,6 @@ sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) fprintf(stderr, "%s: BN_new failed\n", __func__); goto out; } - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != - NID_X9_62_prime_field) { - fprintf(stderr, "%s: group is not a prime field\n", __func__); - goto out; - } if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, NULL) != 1) { fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n", @@ -2935,7 +3044,7 @@ private2_uudecode(struct sshbuf *blob, struct sshbuf **decodedp) goto out; } encoded_len = sshbuf_len(blob); - + #ifdef SUPPORT_CRLF if ((encoded_len < (MARK_BEGIN_LEN + MARK_END_LEN) || memcmp(cp, MARK_BEGIN, MARK_BEGIN_LEN) != 0) && @@ -3283,10 +3392,6 @@ sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf, r = SSH_ERR_ALLOC_FAIL; goto out; } - if (format == SSHKEY_PRIVATE_PKCS8 && (pkey = EVP_PKEY_new()) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto out; - } if ((r = sshkey_unshield_private(key)) != 0) goto out; @@ -3297,6 +3402,10 @@ sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf, success = PEM_write_bio_DSAPrivateKey(bio, key->dsa, cipher, passphrase, len, NULL, NULL); } else { + if ((pkey = EVP_PKEY_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } success = EVP_PKEY_set1_DSA(pkey, key->dsa); } break; @@ -3304,19 +3413,25 @@ sshkey_private_to_blob_pem_pkcs8(struct sshkey *key, struct sshbuf *buf, #ifdef OPENSSL_HAS_ECC case KEY_ECDSA: if (format == SSHKEY_PRIVATE_PEM) { - success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa, + success = PEM_write_bio_ECPrivateKey(bio, + EVP_PKEY_get0_EC_KEY(key->pkey), cipher, passphrase, len, NULL, NULL); } else { - success = EVP_PKEY_set1_EC_KEY(pkey, key->ecdsa); + pkey = key->pkey; + EVP_PKEY_up_ref(key->pkey); + success = 1; } break; #endif case KEY_RSA: if (format == SSHKEY_PRIVATE_PEM) { - success = PEM_write_bio_RSAPrivateKey(bio, key->rsa, + success = PEM_write_bio_RSAPrivateKey(bio, + EVP_PKEY_get0_RSA(key->pkey), cipher, passphrase, len, NULL, NULL); } else { - success = EVP_PKEY_set1_RSA(pkey, key->rsa); + pkey = key->pkey; + EVP_PKEY_up_ref(key->pkey); + success = 1; } break; default: @@ -3485,6 +3600,8 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, struct sshkey *prv = NULL; BIO *bio = NULL; int r; + RSA *rsa = NULL; + EC_KEY *ecdsa = NULL; if (keyp != NULL) *keyp = NULL; @@ -3518,15 +3635,21 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, r = SSH_ERR_ALLOC_FAIL; goto out; } - prv->rsa = EVP_PKEY_get1_RSA(pk); + if ((rsa = EVP_PKEY_get1_RSA(pk)) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } prv->type = KEY_RSA; #ifdef DEBUG_PK - RSA_print_fp(stderr, prv->rsa, 8); + RSA_print_fp(stderr, rsa, 8); #endif - if (RSA_blinding_on(prv->rsa, NULL) != 1) { + if (RSA_blinding_on(rsa, NULL) != 1 || + EVP_PKEY_set1_RSA(pk, rsa) != 1) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } + EVP_PKEY_up_ref(pk); + prv->pkey = pk; if ((r = sshkey_check_rsa_length(prv, 0)) != 0) goto out; #ifdef WITH_DSA @@ -3549,21 +3672,25 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, r = SSH_ERR_ALLOC_FAIL; goto out; } - prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk); + if ((prv->ecdsa_nid = sshkey_ecdsa_fixup_group(pk)) == -1 || + (ecdsa = EVP_PKEY_get1_EC_KEY(pk)) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } prv->type = KEY_ECDSA; - prv->ecdsa_nid = sshkey_ecdsa_key_to_nid(prv->ecdsa); - if (prv->ecdsa_nid == -1 || - sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL || - sshkey_ec_validate_public(EC_KEY_get0_group(prv->ecdsa), - EC_KEY_get0_public_key(prv->ecdsa)) != 0 || - sshkey_ec_validate_private(prv->ecdsa) != 0) { + if (sshkey_curve_nid_to_name(prv->ecdsa_nid) == NULL || + sshkey_ec_validate_public(EC_KEY_get0_group(ecdsa), + EC_KEY_get0_public_key(ecdsa)) != 0 || + sshkey_ec_validate_private(ecdsa) != 0) { r = SSH_ERR_INVALID_FORMAT; goto out; } -# ifdef DEBUG_PK - if (prv != NULL && prv->ecdsa != NULL) - sshkey_dump_ec_key(prv->ecdsa); -# endif + EVP_PKEY_up_ref(pk); + prv->pkey = pk; +#ifdef DEBUG_PK + if (prv != NULL && prv->pkey != NULL) + sshkey_dump_ec_key(EVP_PKEY_get0_EC_KEY(prv->pkey)); +#endif #endif /* OPENSSL_HAS_ECC */ #ifdef OPENSSL_HAS_ED25519 } else if (EVP_PKEY_base_id(pk) == EVP_PKEY_ED25519 && @@ -3598,9 +3725,9 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, /* Append the public key to our private key */ memcpy(prv->ed25519_sk + (ED25519_SK_SZ - ED25519_PK_SZ), prv->ed25519_pk, ED25519_PK_SZ); -# ifdef DEBUG_PK +#ifdef DEBUG_PK sshbuf_dump_data(prv->ed25519_sk, ED25519_SK_SZ, stderr); -# endif +#endif #endif /* OPENSSL_HAS_ED25519 */ } else { r = SSH_ERR_INVALID_FORMAT; @@ -3614,6 +3741,10 @@ sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type, out: BIO_free(bio); EVP_PKEY_free(pk); + RSA_free(rsa); +#ifdef OPENSSL_HAS_ECC + EC_KEY_free(ecdsa); +#endif sshkey_free(prv); return r; } diff --git a/sshkey.h b/sshkey.h index 32933bbbdb8..19bbbac7dc0 100644 --- a/sshkey.h +++ b/sshkey.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.h,v 1.63 2024/05/17 06:42:04 jsg Exp $ */ +/* $OpenBSD: sshkey.h,v 1.66 2025/04/02 04:28:03 tb Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -30,7 +30,10 @@ #ifdef WITH_OPENSSL #include +#ifdef WITH_DSA #include +#endif +#include # ifdef OPENSSL_HAS_ECC # include # include @@ -47,6 +50,7 @@ # define EC_KEY void # define EC_GROUP void # define EC_POINT void +# define EVP_PKEY void #define SSH_OPENSSL_VERSION "without OpenSSL" #endif /* WITH_OPENSSL */ @@ -125,13 +129,12 @@ struct sshkey_cert { struct sshkey { int type; int flags; - /* KEY_RSA */ - RSA *rsa; /* KEY_DSA */ DSA *dsa; /* KEY_ECDSA and KEY_ECDSA_SK */ int ecdsa_nid; /* NID of curve */ - EC_KEY *ecdsa; + /* libcrypto-backed keys */ + EVP_PKEY *pkey; /* KEY_ED25519 and KEY_ED25519_SK */ u_char *ed25519_sk; u_char *ed25519_pk; @@ -223,6 +226,7 @@ int sshkey_shield_private(struct sshkey *); int sshkey_unshield_private(struct sshkey *); int sshkey_type_from_name(const char *); +int sshkey_type_from_shortname(const char *); int sshkey_is_cert(const struct sshkey *); int sshkey_is_sk(const struct sshkey *); int sshkey_type_is_cert(int); @@ -258,7 +262,8 @@ int sshkey_curve_name_to_nid(const char *); const char * sshkey_curve_nid_to_name(int); u_int sshkey_curve_nid_to_bits(int); int sshkey_ecdsa_bits_to_nid(int); -int sshkey_ecdsa_key_to_nid(EC_KEY *); +int sshkey_ecdsa_key_to_nid(const EC_KEY *); +int sshkey_ecdsa_pkey_to_nid(EVP_PKEY *); int sshkey_ec_nid_to_hash_alg(int nid); int sshkey_ec_validate_public(const EC_GROUP *, const EC_POINT *); int sshkey_ec_validate_private(const EC_KEY *); @@ -287,6 +292,12 @@ int sshkey_check_sigtype(const u_char *, size_t, const char *); const char *sshkey_sigalg_by_name(const char *); int sshkey_get_sigtype(const u_char *, size_t, char **); +/* Signing and verification backend for libcrypto-backed keys */ +int sshkey_pkey_digest_sign(EVP_PKEY*, int, u_char **, + size_t *, const u_char *, size_t); +int sshkey_pkey_digest_verify(EVP_PKEY *, int, const u_char *, + size_t, u_char *, size_t); + /* for debug */ void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *); void sshkey_dump_ec_key(const EC_KEY *); @@ -310,7 +321,8 @@ int sshkey_parse_pubkey_from_private_fileblob_type(struct sshbuf *blob, int sshkey_check_rsa_length(const struct sshkey *, int); /* XXX should be internal, but used by ssh-keygen */ -int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *); +int ssh_rsa_complete_crt_parameters(const BIGNUM *, const BIGNUM *, + const BIGNUM *, const BIGNUM *, BIGNUM **, BIGNUM **); /* stateful keys (e.g. XMSS) */ int sshkey_set_filename(struct sshkey *, const char *); @@ -321,6 +333,10 @@ int sshkey_private_serialize_maxsign(struct sshkey *key, void sshkey_sig_details_free(struct sshkey_sig_details *); +#ifdef WITH_OPENSSL +int sshkey_ecdsa_fixup_group(EVP_PKEY *k); /* ssh-ecdsa.c */ +#endif + #ifdef SSHKEY_INTERNAL int sshkey_sk_fields_equal(const struct sshkey *a, const struct sshkey *b); void sshkey_sk_cleanup(struct sshkey *k); @@ -341,6 +357,7 @@ int check_rsa_length(const RSA *rsa); /* XXX remove */ # undef EC_KEY # undef EC_GROUP # undef EC_POINT +# undef EVP_PKEY #elif !defined(OPENSSL_HAS_ECC) # undef EC_KEY # undef EC_GROUP diff --git a/sshsig.c b/sshsig.c index 293ca61a7ff..ed22e15d571 100644 --- a/sshsig.c +++ b/sshsig.c @@ -43,9 +43,9 @@ #define MAGIC_PREAMBLE_LEN (sizeof(MAGIC_PREAMBLE) - 1) #define BEGIN_SIGNATURE "-----BEGIN SSH SIGNATURE-----" #define END_SIGNATURE "-----END SSH SIGNATURE-----" -#define RSA_SIGN_ALG "rsa-sha2-512" /* XXX maybe make configurable */ +#define RSA_SIGN_ALG "rsa-sha2-512" #define RSA_SIGN_ALLOWED "rsa-sha2-512,rsa-sha2-256" -#define HASHALG_DEFAULT "sha512" /* XXX maybe make configurable */ +#define HASHALG_DEFAULT "sha512" #define HASHALG_ALLOWED "sha256,sha512" int @@ -193,8 +193,13 @@ sshsig_wrap_sign(struct sshkey *key, const char *hashalg, } /* If using RSA keys then default to a good signature algorithm */ - if (sshkey_type_plain(key->type) == KEY_RSA) + if (sshkey_type_plain(key->type) == KEY_RSA) { sign_alg = RSA_SIGN_ALG; + if (strcmp(hashalg, "sha256") == 0) + sign_alg = "rsa-sha2-256"; + else if (strcmp(hashalg, "sha512") == 0) + sign_alg = "rsa-sha2-512"; + } if (signer != NULL) { if ((r = signer(key, &sig, &slen, diff --git a/version.h b/version.h index c737c2ae14c..46da6bd38ce 100644 --- a/version.h +++ b/version.h @@ -1,6 +1,6 @@ -/* $OpenBSD: version.h,v 1.102 2024/07/01 04:31:59 djm Exp $ */ +/* $OpenBSD: version.h,v 1.105 2025/04/09 07:00:21 djm Exp $ */ -#define SSH_WINDOWS_VERSION "OpenSSH_for_Windows_9.8" +#define SSH_WINDOWS_VERSION "OpenSSH_for_Windows_10.0" #define SSH_WINDOWS_BANNER " Win32-OpenSSH-GitHub" #define SSH_VERSION SSH_WINDOWS_VERSION SSH_WINDOWS_BANNER