Re: Новый сервер GUARDANT NET

Спасибо за ответы.
Они точно являются правильными для ключей Guardant Net II?

Антон Тихиенко пишет:

Должен равняться адресу, по которому расположена таблица лицензий, например для маски по умолчанию + таблица лицензий = 102(UAM) или 132(SAM).

То есть, в GrdProtect() можно использовать и SAM и UAM адресацию?

Re: Новый сервер GUARDANT NET

AndreyStepin пишет:

Да, новый сервер работает только с таблицей лицензий даже в ключах Net II. Старый читал значения из других мест, в том числе 38SAM + счетчик 2.

Итак, при программировании ключа Net II я должен занести реальный ресурс в 38SAM, а также создать таблицу лицензий с первой записью равной реальному ресурсу.
Но, в действительности, мы не пользуемся возможностью ограничить количество лицензий. То есть, я должен прочитать максимальное количество лицензий (19SAM) и занести его и в 38SAM и LMS. Правильно?
А для Stealth III Sign Net то же самое?

И как мне из клиентского приложения узнать реальное количество лицензий (с учетом возможных ограничений)? Из TGrdFindInfo::wRealNetRes? Это работает для всех версий ключей и для всех версий серверов?

А можно ли как-то узнать количество задействованных в данный момент лицензий?

Re: Новый сервер GUARDANT NET

Luck пишет:

Спасибо за ответы.
Они точно являются правильными для ключей Guardant Net II?

Да, за исключением размещения таблицы лицензий, для ключей Net II ее все таки следует размещать после последней защищенной ячейки (алгоритма). Для более современных моделей сетевых ключей данная размещать таблицу лицензий возможно и между другими  защищенными ячейками.

Luck пишет:

То есть, в GrdProtect() можно использовать и SAM и UAM адресацию?

Аппаратные запреты можно устанавливать на непрерывную область памяти ключа, начиная с адреса 44 SAM = 14 UAM (в соответствующем режиме работы хэндла, который устанавливается функцией GrdSetWorkMode).

Luck пишет:

Итак, при программировании ключа Net II я должен занести реальный ресурс в 38SAM, а также создать таблицу лицензий с первой записью равной реальному ресурсу.

Да.

Luck пишет:

Но, в действительности, мы не пользуемся возможностью ограничить количество лицензий. То есть, я должен прочитать максимальное количество лицензий (19SAM) и занести его и в 38SAM и LMS. Правильно?

Да.

Luck пишет:

А для Stealth III Sign Net то же самое?

Для ключей Net III и Sign Net общий сетевой ресурс (19SAM) нужно будет поместить в защищенную ячейку (где записывается таблица лицензий) со смещением 16 (см. 2 часть руководства пользователя Guardant, стр.33).

Luck пишет:

И как мне из клиентского приложения узнать реальное количество лицензий (с учетом возможных ограничений)? Из TGrdFindInfo::wRealNetRes? Это работает для всех версий ключей и для всех версий серверов?

Да.

Luck пишет:

А можно ли как-то узнать количество задействованных в данный момент лицензий?

Только при помощи стандартного web-интерфейса монитора сервера сетевых ключей, либо парсить данные этого же web-монитора, и таким образом получать информацию о текущем состоянии ключа.

Отдельно хочу уточнить, с какими конкретно фактическими проблемами Вы столкнулись в процессе написания и отладки своей утилиты? Или изложенные выше вопросы носят только теоретический характер?
Дело в том, что большинство их покрывается данными из нашей документации (Руководство пользователя и справка по Guardant API).

Re: Новый сервер GUARDANT NET

Антон Тихиенко пишет:

Отдельно хочу уточнить...

Существует 3-4 поколений ключей, 2 поколения API, 2 поколения серверов. И в их декартовом произведении я несколько теряюсь. Документацию я читал и читаю, включая и прошлые версии. А спрашиваю то, что или неясно из документации, либо имеет противоречия, либо вызывает какие-то сомнения. К сожалению, последние ответы ясности не добавили, а, скорее, наоборот

Давайте разбираться.
Сейчаc меня интересует процесс программирования ключей Stealth I, Stealth II, Net II при помощи современного API. Есть давно работающий код вида:

nskRead()
nskRead()
nskInit()
nskWrite()
nskWrite()
nskWrite()
nskWrite()
nskProtect()

который просто заливает в ключ буфер с алгоритмами, программирует некоторые отдельные ячейки и все это защищает. Его нужно перевести на GrdXXX API, а также добавить для Net II таблицу лицензий для совместимости с сервером 6.2.

Насколько я помню, функция nskProtect() использовала адресацию в SAM-словах, независимо от настроек режима SAM/UAM

Нынешний ее аналог, GrdProtect(), судя по документации, теперь использует адресацию в SAM-байтах, также независимо от настроек SAM/UAM. Но почему-то есть одно исключение - dwTableLMS для Net II по прежнему использует адресацию в словах. Это действительно так, или это все-таки опечатка в руководстве?

Антон Тихиенко пишет:
Luck пишет:

В Net II таблица лицензий должна располагаться после таблицы алгоритмов?

Да, потому что таблица лицензий – это вид защищенной ячейки/алгоритма.

Так, вроде, защищенные ячейки появились только в Stealth III. А раньше были только алгоритмы. LMS разве относится к алгоритмам?

В документации по GrdProtect() сказано

[NET III]
dwNumFunc - количество аппаратных алгоритмов и защищенных ячеек (Protected Item), дескрипторы которых записаны в память ключа
[NET II]
dwNumFunc - количество аппаратных алгоритмов, дескрипторы которых записаны в память ключа

То есть, вроде как, dwNumFunc должна включать LMS, если это NET III, и не должна, если это NET II?

По поводу необходимости защиты LMS от чтения у меня тоже были сомнения. Тем более, разные версии GrdUtil имеют на этот счет различное мнение. Из ваших ответов я понял, что LMS должны быть защищена и от чтения, и от записи для всех типов ключей (II и III)

Re: Новый сервер GUARDANT NET

Luck пишет:

Насколько я помню, функция nskProtect() использовала адресацию в SAM-словах, независимо от настроек режима SAM/UAM

Нынешний ее аналог, GrdProtect(), судя по документации, теперь использует адресацию в SAM-байтах, также независимо от настроек SAM/UAM. Но почему-то есть одно исключение - dwTableLMS для Net II по прежнему использует адресацию в словах. Это действительно так, или это все-таки опечатка в руководстве?

Это не опечатка, действительно так и есть.

Luck пишет:
Антон Тихиенко пишет:
Luck пишет:

В Net II таблица лицензий должна располагаться после таблицы алгоритмов?

Да, потому что таблица лицензий – это вид защищенной ячейки/алгоритма.

Так, вроде, защищенные ячейки появились только в Stealth III. А раньше были только алгоритмы. LMS разве относится к алгоритмам?

В документации по GrdProtect() сказано

[NET III]
dwNumFunc - количество аппаратных алгоритмов и защищенных ячеек (Protected Item), дескрипторы которых записаны в память ключа
[NET II]
dwNumFunc - количество аппаратных алгоритмов, дескрипторы которых записаны в память ключа

То есть, вроде как, dwNumFunc должна включать LMS, если это NET III, и не должна, если это NET II?

Да, все верно. Что касается реализации защищенных ячеек в ключах Stealth II/Net II, то тут Вы также совершенно правы, защищенных ячеек в данных ключах еще не было. Прошу прощения, мое упущение.

Luck пишет:

По поводу необходимости защиты LMS от чтения у меня тоже были сомнения. Тем более, разные версии GrdUtil имеют на этот счет различное мнение. Из ваших ответов я понял, что LMS должны быть защищена и от чтения, и от записи для всех типов ключей (II и III)

Таблицу лицензий необходимо защищать на запись, по крайней мере по версии GrdUtil 5.xx и 6.хх релизов.

Re: Новый сервер GUARDANT NET

Берем GrdUtil от версии 6.2 (демо коды).

Создаем маску ключа Stealth I. По умолчанию в ней 4 алгоритма. Сохраняем Исходный код записи (он с сокращениями приведен ниже) .

Алгоритмы заканчиваются по адресу 78 УАМ, то есть 108 САМ. А в исходном коде мы видим:

GrdProtect(hGrd,  77,  77,  4,  0,  0, NULL)

В документации про параметры dwWrProt и dwRdProt сказано:

SAM-адрес первого байта, доступного для записи (в байтах). Адрес должен быть четным, в противном случае возвращается ошибка GrdE_InvalidArg

Почему нам предлагают поставить защиту до 77 адреса? Разве не 108 должно быть? Кстати, 77 еще и нечетное.



...
const unsigned char g_byDongleImage[] = {\
    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x20, \
    0x28, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0xD3, 0xF5, \
    0x4D, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
    0x08, 0x20, 0x12, 0x79, 0x64, 0x73, 0x37, 0x16, \
    0xF4, 0x73, 0x06, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, \
    0x04, 0x04, 0x91, 0xE2, 0x03, 0x5E, 0x00, 0x00, \
    0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x78, 0x54, \
    0xA3, 0x22, 0x17, 0xE2, 0xFE, 0x61};

int main(int argc, char* argv[])
{
......................
    if(::GrdWrite(hGrd, GrdUAM_bNProg, sizeof(g_byDongleImage), (void*)g_byDongleImage, NULL) == GrdE_OK)
    {
        if(::GrdProtect(hGrd,  77,  77,  4,  0,  0, NULL) == GrdE_OK)
        {
            printf("Dongle image has been successfully written to the dongle");
        }
    }
......................
    
    return nLastError;
}

Re: Новый сервер GUARDANT NET

Здравствуйте.

Luck пишет:

Почему нам предлагают поставить защиту до 77 адреса? Разве не 108 должно быть?

Такое поведение похоже на некорректную работу указанной функции (Исходный код записи) в GrdUtil. Правильнее тут будет в первую очередь (до вызова GrdWrite) выставлять нужный режим адресации (функция GrdSetWorkMode, если ее не применять, то, по умолчанию, будет использоваться UAM-режим) и только после этого выполнять запись с указанием нужных адресов в SAM-режиме адресации.

Luck пишет:

Кстати, 77 еще и нечетное.

Уточните, пожалуйста, точнее (предоставьте скриншоты сведений о программе из GrdUtil (Меню "Файл" -> пункт "О Программе" и скриншот свойств файла "GrdUtil.exe" -> вкладка "Подробно")) какой именно версии GrdUtil используется? Такое поведение было характерно для комплектов разработчика 6.х версий до выхода версии 6.2. 

Указанные ошибки будут перепроверены и исправлены.

Re: Новый сервер GUARDANT NET

Антон Тихиенко пишет:

Такое поведение похоже на некорректную работу указанной функции (Исходный код записи) в GrdUtil.

Похоже, дело не только в функции (Исходный код записи). В статус-баре также указано 77/77.

Антон Тихиенко пишет:

Правильнее тут будет в первую очередь (до вызова GrdWrite) выставлять нужный режим адресации (функция GrdSetWorkMode, если ее не применять, то, по умолчанию, будет использоваться UAM-режим) и только после этого выполнять запись с указанием нужных адресов в SAM-режиме адресации.

Справочная система по Guardant API 6.0 пишет:

Функция GrdProtect - установка аппаратных запретов
...
dwWrProt -SAM-адрес первого байта, доступного для записи (в байтах). Адрес должен быть четным, в противном случае возвращается ошибка GrdE_InvalidArg

Казалось бы, GrdProtect() всегда использует SAM, и не обращает внимание на режим, установленный GrdSetWorkMode()

http://s3.hostingkartinok.com/uploads/images/2013/05/55aeea696c9d7df9572a8c5e739e21e6.png


PS
Не удалось залить картинку на ваш форум.

undefined (undefined) - Файл превышает допустимый размер и не будет загружен (2000000)

- независимо от формата и размера картинки

(2013-05-21 16:25:03 отредактировано Антон Тихиенко)

Re: Новый сервер GUARDANT NET

Luck пишет:

Похоже, дело не только в функции (Исходный код записи). В статус-баре также указано 77/77.

Да, Вы правы. Это похоже на ошибку в генерируемой прошивке старых ключей.
Спасибо за информацию!

Re: Новый сервер GUARDANT NET

Продолжаем разговор...

Речь пойдет о ключах Sign и современном SDK 7.0

Создаем пустую маску Sign.
http://s7.hostingkartinok.com/uploads/images/2015/02/c495c2d593a8ecfba4bbd4d44842fd33.png
В статус-баре указано, что защиту нужно ставить на адрес 39. Смотрим Исходный Код Записи - там тоже GrdProtect(hGrd,  3939,  0,  0,  0, NULL). Но почему?
Левая колонке таблицы - это, как я понимаю, UAM-адрес. Мы видим, что свободная память начинается с 40uam, а 39uam - это последняя защищаемая ячейка. В документации сказано, что в функцию GrdProtect() нужно передать SAM адрес первой незащищенной ячейки, то есть, это должно быть 40uam+30=70sam.
Прошиваем ключ и смотрим байты 10uam и 12uam - там 70. То есть ключ прошивается правильно, а пользователю показывается чепуха!


Добавим какой-нибудь алгоритм.
http://s7.hostingkartinok.com/uploads/images/2015/02/25198c1b813d945be3e429b449f45414.png
Теперь статусбар предлагает нам установить защиту на 135, Исходный Код Записи - тоже 135. А левая колонка и документация подсказывают, что защищать нужно 136sam+30=166uam!
Прошиваем ключ - так и есть, там 166. На экране и с cpp-файле опять чушь, но ключ опять прошит верно!

Итак, в GrdUtil есть две ошибки:
1) На 1 байт - из-за путаницы: (первый незащищенный байт) <-> (последний защищенный)
2) На 30 байт - из за путаницы: SAM<->UAM
Итого, программа врет на 31 байт.


Попробуем теперь отключить защиту памяти.
http://s7.hostingkartinok.com/uploads/images/2015/02/c09faaa0a768efaf65b40e8940663e61.png
Документация говорит нам, что в этом случае нужно в GrdProtect() передать 0. Статусбар согласем с документацией - там нули. Исходный Код Записи того же мнения - там тоже 0.
Прошиваем ключ - там 31! Теперь, наоборот, в ключ прошита ерунда, а на экране и в cpp все нормально!

Может, я чего-то не понимаю?

Re: Новый сервер GUARDANT NET

Здравствуйте, Luck.

Тут действительно есть огрехи в GrdUtil, но они не совсем правильно интерпретированы.

По первым двум скриншотам - статусбар показывает все правильно и указанны тут байты, до которых, включительно, защита (на чтение\запись) установлена. А вот в исходном коде записи действительно ошибка, там должен быть указан первый незащищенный байт.

Третий же скриншот показывает на ошибкув интерфейсе, т.к. с полей общего назначения нельзя снять защиту, что и происходит при программировании ключа, т.е. прошивается ключ правильно.

Re: Новый сервер GUARDANT NET

Антон Тихиенко пишет:

По первым двум скриншотам - статусбар показывает все правильно и указаны тут байты, до которых, включительно, защита (на чтение\запись) установлена.

Хорошо, пусть статусбар показывает последний защищенный байт. А в какой адресации?

Антон Тихиенко пишет:

А вот в исходном коде записи действительно ошибка, там должен быть указан первый незащищенный байт...

... в системе SAM. А реально там UAM-адрес, уменьшенный на 1.

Антон Тихиенко пишет:

Третий же скриншот показывает на ошибку в интерфейсе, т.к. с полей общего назначения нельзя снять защиту, что и происходит при программировании ключа, т.е. прошивается ключ правильно.

А это я не понял. Согласно документации, защиту можно устанавить на четный адрес памяти, начиная с 44sam. То есть, если защита установлена на 44sam, то, фактически, она отсутствует. Но для отключения защиты документация рекомендует устанавливать 0. Так что, в третьем случае, защита должна быть установлена на 0, или на худой конец, на 44sam. А реально она ставится на 31 (нечетное число). Разве это правильно?

Re: Новый сервер GUARDANT NET

Luck пишет:

А это я не понял. Согласно документации, защиту можно устанавить на четный адрес памяти, начиная с 44sam. То есть, если защита установлена на 44sam, то, фактически, она отсутствует. Но для отключения защиты документация рекомендует устанавливать 0. Так что, в третьем случае, защита должна быть установлена на 0, или на худой конец, на 44sam. А реально она ставится на 31 (нечетное число). Разве это правильно?

Прошу прощения, я ошибся, тут имеются ввиду поля свободного назначения, а точнее, только защищенные ячейки и их частные случаи (аппаратные алгоритмы и таблица лицензий), которые всегда записываются с запретами.

(2015-02-17 12:12:12 отредактировано Luck)

Re: Новый сервер GUARDANT NET

Еще столкнулись с такой проблемой.

После перехода на версию 7 программа, запущенная из ProgramFiles, перестала видеть ключ. Та же программа, запущенная из другой директории, ключ видит нормально.

По-видимому, причина в том, что программа пытается создать файл gnclient.ini рядом с собой. В ProgramFiles это запрещено и она обламывается. Это проявляется даже на сугубо локальных программах.

Какая АПИ функция создает gnclient.ini?

Как исправить эту ошибку?

Re: Новый сервер GUARDANT NET

Поизучал проблему.

Тот же самый эффект наблюдается, если рядом с exe-файлом создать подкаталог gnclient.ini.

Функция GrsStartup(), если ей указан флаг Remote, пытается создать файл gnclient.ini. Если создать этот файл не удается, то она возвращает ошибку 9.

Раньше (версия АПИ 6.0) такого эффекта не наблюдалось.

Так как же все-таки заставить работать программу, установленную в ProgramFiles?

Re: Новый сервер GUARDANT NET

Guardant API, из состава SDK 6.0, не "умело" генерировать конфигурационный файл "gnclient.ini".
Сейчас нужно пользоваться функцией GrdStartupEx для того, чтобы указать директорию, куда будет помещаться файл "gnclient.ini".

Re: Новый сервер GUARDANT NET

Спасибо! Не сразу, но помогло.
Хорошо бы в документации указать, что имя директории, куда будет помещаться файл "gnclient.ini", должно заканчиваться слешем, иначе будет ошибка 97.

Да, и для Windows неплохо было бы иметь WideChar версию GrdStartupEx().

Re: Новый сервер GUARDANT NET

Luck пишет:

Спасибо! Не сразу, но помогло.
Хорошо бы в документации указать, что имя директории, куда будет помещаться файл "gnclient.ini", должно заканчиваться слешем, иначе будет ошибка 97.

Да, и для Windows неплохо было бы иметь WideChar версию GrdStartupEx().

Спасибо. Замечания учтем.

(2015-03-18 12:34:32 отредактировано Luck)

Re: Новый сервер GUARDANT NET

Антон Тихиенко пишет:
Luck пишет:

И как мне из клиентского приложения узнать реальное количество лицензий (с учетом возможных ограничений)? Из TGrdFindInfo::wRealNetRes? Это работает для всех версий ключей и для всех версий серверов?

Да.

Ответ неверный.

Для Guardant SP мы используем шаблон на 255 лицензий. Реальное же количество лицензий задается на сервере. Обсуждение этой технологии было здесь.
Оказалось, что в этом случае TGrdFindInfo::wRealNetRes равно 255, а TGrdFindInfo::wMaxNetRes равно реальному количеству лицензий.
Это ошибка в АПИ? Или в драйвере?
Или это так и задумано? Тогда какой в этом смысл?

Так как же все-таки узнать количество лицензий, реально доступных пользователю?
Можно, конечно, забить костыль, типа

int GetReallyRealNetRes(const TGrdFindInfo &FindInfo)
{
  if (FindInfo.dwModel==xxxGrdSP)
    return FindInfo.wMaxNetRes;
  return FindInfo.wRealNetRes;
}

Но не сломается ли он после обновления драйвера?

Re: Новый сервер GUARDANT NET

Luck пишет:
Антон Тихиенко пишет:
Luck пишет:

И как мне из клиентского приложения узнать реальное количество лицензий (с учетом возможных ограничений)? Из TGrdFindInfo::wRealNetRes? Это работает для всех версий ключей и для всех версий серверов?

Да.

Ответ неверный.

Пару лет назад, очевидно, данный вопрос был не совсем корректно мной истолкован, однако, ошибок нет - реальный сетевой ресурс (wRealNetRes) это именно то число, которое записывается разработчиком при программировании электронного ключа и TGrdFindInfo::wRealNetRes работает корректно для всех ключей.

Таким образом значения реального сетевого ресурса (wRealNetRes) и максимального (byMaxNetRes), по желанию разработчика, могут отличаться друг от друга. С обновлением драйверов ничего не сломается.

Re: Новый сервер GUARDANT NET

С каждым следующим поколением ключей у вас увеличивается количество мест, где хранятся сетевые ресурсы

Сначала ресурс хранился в ключе в двух местах: 19sam и 38sam.
Потом в трех местах: 19sam, 38sam и LMS
А в GuardantSPNet он хранится уже в четырех местах: 19sam, 38sam, LMS и sp.guardant.ru

Но конечного пользователя не интересуют эти подробности. Ему нужно лишь знать, сколько рабочих мест он реально может подключить к этому ключу. Так как получить это значение?
Я полагал, что TGrdFindInfo::wRealNetRes - это как раз то,что нужно. Оказывается, нет.

Может, нужно брать минимум из TGrdFindInfo::wRealNetRes и byMaxNetRes?

Но byMaxNetRes - это 1 байт. Тогда, получается, ключ может быть максимум на 255 пользователей, но это ведь не так?

Re: Новый сервер GUARDANT NET

Luck пишет:

Может, нужно брать минимум из TGrdFindInfo::wRealNetRes и byMaxNetRes?

Да, все верно.

wRealNetRes; // Текущий ресурс лицензий сетевого ключа. Задается разработчиком, должен быть <= byMaxNetRes
Luck пишет:

Но byMaxNetRes - это 1 байт. Тогда, получается, ключ может быть максимум на 255 пользователей, но это ведь не так?

Здесь ошибка, исправление которой войдет в весеннее обновление Guardant SDK.

Re: Новый сервер GUARDANT NET

А как быть с файлом gnclient.ini при переходе с 5-го сервера на 7 (API тоже изменилось с 6 на 7)?
Клиенты жалуются, что старый, работавший gnclient.ini перезаписывается новым, пустым и неработающим.

Re: Новый сервер GUARDANT NET

Luck пишет:

А как быть с файлом gnclient.ini при переходе с 5-го сервера на 7 (API тоже изменилось с 6 на 7)?
Клиенты жалуются, что старый, работавший gnclient.ini перезаписывается новым, пустым и неработающим.

Тут не совсем понятно, в составе дистрибутива приложения, защищенного при помощи Guardant API 7 версии, поставляется "старый" конфигурационный файл gnclient.ini?

Re: Новый сервер GUARDANT NET

Раньше наше приложение защищалось Guardant API 6, использовался старый сервер 5.5, и у пользователей были настроенные для их среды файлы gnclient.ini. Наша программа установки-обновления никак не затрагивает gnclient.ini.
Новая версия приложения использует Guardant API 7. Пользователи обновляют программу, устанавливают новый седьмой сервер, gnclient.ini остается прежним. При запуске приложения ключ не находится, а старый gnclient.ini исчезает и заменяется на новый, пустой.